标签 PHP 下的文章

PHP 有一个 echo 标记简写 <?=, 它是更完整的 <?php echo 的简写形式。

<?= 'Hello World' ?>

使用条件的高级分离术:PHP 将跳过条件语句未达成的段落,即使该段落位于 PHP 开始和结束标记之外。由于 PHP 解释器会在条件未达成时直接跳过该段条件语句块,因此 PHP 会根据条件来忽略之。

要输出大段文本时,跳出 PHP 解析模式通常比将文本通过 echo 或 print 输出更有效率。

<?php if ($expression == true): ?>
  This will show if the expression is true.
<?php else: ?>
  Otherwise this will show.
<?php endif; ?>

如果只是想得到一个易读懂的类型的表达方式用于调试,用 gettype() 函数。要检验某个类型,不要用 gettype() ,而用 is_type 函数(如 is_int() )。

PHP 中的类型强制转换和 C 中的非常像:在要转换的变量之前加上用括号括起来的目标类型。

<?php
$foo = 10;   // $foo is an integer
$bar = (boolean) $foo;   // $bar is a boolean
?>

可变变量:

<?php
$a = 'hello';
$$a = 'world'; // $$a == $hello
echo "$a ${$a}";  // hello world
echo "$a $hello"; // hello world

form 表单中,变量名中的点和空格被转换成下划线。例如 <input name="a.b" /> 变成了 $_REQUEST["a_b"]

IMAGE SUBMIT 变量名:当提交表单时,可以用一幅图像代替标准的提交按钮,用类似这样的标记:

<input type="image" src="image.gif" name="sub" />

当用户点击到图像中的某处时,相应的表单会被传送到服务器,并加上两个变量 sub_x 和 sub_y。它们包含了用户点击图像的坐标。有经验的用户可能会注意到被浏览器发送的实际变量名包含的是一个点而不是下划线(即 sub.x 和 sub.y),但 PHP 自动将点转换成了下划线。

函数的返回值是数组的情况。

<?php
function small_numbers()
{
    return [0, 1, 2];
}
// 使用短数组语法将数组中的值赋给一组变量
[$zero, $one, $two] = small_numbers();

// 在 7.1.0 之前,唯一相等的选择是使用 list() 结构
list($zero, $one, $two) = small_numbers();
?>

PHP 7 中的 ?? 操作。

$i = 0;
echo $i ?? 1; //当 $i 存在且不为 null 时,使用 $i ,否则使用 1 .
echo isset($i) ? $i : 1;

推测可能原因:编译时间过长导致任务退出。

解决方案

在经过一次出错后,/www/server/php/74/src/ext/fileinfo/目录下应该已经有下载好的 fileinfo 扩展(这里的74根据版本号进行修改)。

切换到该目录,并执行相关操作。

cd /www/server/php/74/src/ext/fileinfo/

make distclean

./configure --with-php-config=/www/server/php/74/bin/php-config

make

执行完make需要一定时间,耐心等待。执行完毕后,执行:

make install

到面板重载 PHP 配置即可。

参考资料

php_fileinfo宝塔安装不,宝塔面板安装fileinfo扩展报错失败的解决方法_Xi Zi的博客-CSDN博客

使用例

使用 Composer 安装 PHPMailer,然后新建 PHP 文件,填入下方内容。

Correo 是西班牙语的“邮件”之意。本代码节录修改自参考资料#1,原作者可能是西班牙语使用者。

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';
$Correo = new PHPMailer();
$Correo->IsSMTP();
$Correo->CharSet = PHPMailer::CHARSET_UTF8;
$Correo->SMTPAuth = true;
$Correo->SMTPSecure = "tls";
$Correo->Host = "STMP.DOMAIN.EXP";         //服务器地址
$Correo->Port = 587;                     //服务器端口
$Correo->Username = "USER@DOMAIN.EXP";    //用户名
$Correo->Password = "PASSWORD";            //密码
$Correo->SetFrom('USER@DOMAIN.EXP');    //发件人
//$Correo->FromName = "From";            //发件人名
$Correo->AddAddress("RECV@FOXMAIL.COM");//收件人
$Correo->Subject = "服务器连通性测试";
$Correo->Body = "如果您能收到这封邮件,代表服务器邮件通讯正常。这是一封UTF-8格式的编码。";
$Correo->IsHTML (true);
if (!$Correo->Send()) echo "送信失败:$Correo->ErrorInfo";
else echo "送信完成 ~( ̄▽ ̄)~*";
?>

参考资料

  1. 正常送信模板:php - "SMTP Error: Could not authenticate" in PHPMailer - Stack Overflow
  2. UTF-8 解决乱码方案:PHPMailer/PHPMailerTest.php · PHPMailer/PHPMailer
  3. 更多 PHPMailer 参数:a-simple-example | PHPMailer/PHPMailer: The classic email sending library for PHP

前期准备

使用 Composer 下载所需的准备材料。

cd ... #网站根目录
composer require firebase/php-jwt

在 PHP 文件中,需要写入下面的代码,注意目录路径,这里是相对于根目录。

require __DIR__ . '/vendor/autoload.php';
use Firebase\JWT\JWT;

令牌创建

我们使用 Cookie 储存 JWT。

我们需要创建一个自定义字符串作密钥,这里我们存在一个名为key-999d-45a2-a2b3.php的文件中:

<?php
    $key = 'cptbtptp233';
?>

核心部分代码:

// $audience 是用户名。
// $exp 是失效时间,这里设为 1 天。

require 'key-999d-45a2-a2b3.php';
$exp = time() + 24 * 60 * 60;

$payload = array(
"aud" => $audience,
"exp" => $exp
);

$jwt = JWT::encode($payload, $key);
setcookie("token",$jwt,$exp);

值得注意的是,firebase/php-jwt 支持多种不同的算法,在JWT::encode()第三个参数省缺的情况下默认为 HS256 。可以在 https://jwt.io/#libraries-io 查看。若要使用其他算法,例如 HS512 ,需要上述代码将倒数第二行更为:

$jwt = JWT::encode($payload, $key, 'HS512');

令牌校验

创建好后我们就可以根据令牌校验。

require 'key-999d-45a2-a2b3.php';
if(isset($_COOKIE['token'])){
    //如果 COOKIE 存在
    $jwt = $_COOKIE['token'];
    try{
        $decoded = JWT::decode($jwt, $key, array('HS256'));
        $uid = $decoded -> aud; //用户ID
        $exp = $decoded -> exp; //JWT有效期

        if(time() < $exp) $ifLogin = true; //JWT也没过期,通过校验
    } catch(Exception $e){
            //如果JWT被篡改
            echo '你这 JWT 有问题啊:'.$e->getMessage();
    }
}

至此完成。

自 PHP 7.2.0 开始,函数 creat_function() 由于安全原因被弃用。而在一些老版本的插件中仍在使用此函数,我们只需对其进行稍微改动即可正常使用。

例如

creat_function(__A__ , __B__);

只需将其更改为

function(__A__){
   __B__;
}

即可。

我们设时间戳函数名为 $timestamp ,则有

<?php echo date('h:i a' , $timestamp); ?>

输出效果为:

01:03 pm

对比你所要转换的时区。如从格林尼治标准时间(GMT+0)转换到北京标准时间(GMT+8),只需要加上 8 个小时即可。在时间戳中以秒为单位,进行换算有: 8 小时 = 28,800 秒。

所以仅需给 $timestamp 加上 28800 即可。

<?php echo date('h:i a' , $timestamp + 28800 ); ?>

输出效果为:

09:03 pm