王新阳

wangxinyang

php登录后台时一直提示验证码错误

查日志发现是新部署的业务 php/temp 目录没有写入权限

Session: Configured save path 'D:\php\temp' is not writable by the PHP process
Severity: Warning --> session_start(): Failed to initialize storage module: user (path: D:\php\temp\) D:\webroot\system\Session.php 143

PHP按目标比例和尺寸缩小并裁切图片

/**
 * 按目标比例和尺寸缩小并裁切图片,如果原图尺寸小于目标尺寸,则只按比例裁切
 * @param $img_name 原图片名称(不是路径)
 * @param $width 目标图片宽度,如果原图宽度不等于目标宽度,则原图按目标比例缩放后再裁切
 * @param $width 目标图片高度
 */
function img_convert_do($img_name, $width, $height){
	$old_img=FCPATH.'photo/'.$img_name;
	$new_img=FCPATH.'photo2/'.$img_name;
	$size_arr = @getimagesize($old_img);
	if(is_array($size_arr)){
		$w = $size_arr[0];
		$h= $size_arr[1];
	}else{
		exit('图片尺寸获取失败:'.$img_name);
	}
	if($w/$h < $width/$height){
		$h=ceil($w*$height/$width);
	}else if($w/$h > $width/$height){
		$w=ceil($width*$h/$height);
	}else{ //比例一致,直接复制
		return copy($old_img,$new_img);
	}
	if($w<$width){
		$width=$w;
		$height=$h;
	}
		
	//新建真彩色图像
	$im = imagecreatetruecolor($width, $height);
	//为图像分配颜色
	//$color = imagecolorallocate($im, 255,255,255);
	//从指定坐标开始填充颜色
	//imagefill($im, 0,0, $color);
	//从字符串的图像流中新建图像,可以自动识别文件类型,但是比 imagecreatefromjpeg 等多消耗内存
	$source = imagecreatefromstring(file_get_contents($old_img));
/*
从 x、y 坐标 src_x、src_y 开始,将 src_image 的一部分复制到 dst_image 上,
宽度为 src_width,高度为 src_height。定义的部分将被复制到 x,y 坐标 dst_x 和 dst_y 上。
imagecopy(
    GdImage $dst_image,
    GdImage $src_image,
    int $dst_x,
    int $dst_y,
    int $src_x,
    int $src_y,
    int $src_width,
    int $src_height
): bool

从 src_image 中取出一个宽度为 src_width 高度为 src_height 的矩形区域,
在位置(src_x、src_y)
并将其放置在 dst_image 中宽度为 dst_width 高度为 dst_height 的矩形区域中,
位置为(dst_x、dst_y)。
imagecopyresampled(
    GdImage $dst_image,
    GdImage $src_image,
    int $dst_x,
    int $dst_y,
    int $src_x,
    int $src_y,
    int $dst_width,
    int $dst_height,
    int $src_width,
    int $src_height
): bool

输出图象到浏览器或文件
image 由图象创建函数(例如imagecreatetruecolor())返回的 GdImage 对象。
file 文件保存的路径或者已打开的流资源(此方法返回后自动关闭该流资源),如果未设置或为 null,将会直接输出原始图象流。
quality 为可选项,范围从 0(最差质量,文件最小)到 100(最佳质量,文件最大)。默认值(-1)使用 IJG 默认的质量值(大约 75)。
imagejpeg(GdImage $image, resource|string|null $file = null, int $quality = -1): bool
*/
	//执行剪裁(高质量重采样)
	imagecopyresampled($im, $source, 0,0, 0,0, $width,$height, $w,$h);
	imagedestroy($source);
		
	//保存到文件
	imagejpeg($im, $new_img, 90);
	imagedestroy($im);
}

PHP 用 TrueType 字体向图像写入文本

/**
用 TrueType 字体向图像写入文本
image 由图象创建函数(例如imagecreatetruecolor())返回的 GdImage 对象。
size 字体的尺寸,单位:点(磅)。
angle 角度制表示的角度,0 度为从左向右读的文本。较高数值表示逆时针旋转。例如 90 度表示从下向上读的文本。
x 由 x,y 所表示的坐标定义了第一个字符的基本点(大概是字符的左下角)。这和 imagestring() 不同,其中 x,y 定义了第一个字符的左上角。例如“top left”为 0, 0。
Y 坐标。它设定了字体基线的位置,不是字符的最底端。
color 颜色索引。使用负的颜色索引值具有关闭防锯齿的效果。见 imagecolorallocate()。
fontfile 想要使用的 TrueType 字体的路径。
imagettftext(
    GdImage $image,
    float $size,
    float $angle,
    int $x,
    int $y,
    int $color,
    string $font_filename,
    string $text,
    array $options = []
): array|false
*/
// 创建图像
$im = imagecreatetruecolor(300,50);

// 创建一些颜色
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefill($im, 0,0, $white);
// 要绘制的文本
$text = '用 TrueType 字体向图像写入文本';
// 用自己的字体路径替换路径
$font = 'ttf字体文件路径';
// 给文本添加一些阴影
imagettftext($im, 20, 0, 11, 31, $grey, $font, $text);
// 添加文本
imagettftext($im, 20, 0, 10, 30, $black, $font, $text);
// 设置 content-type
header('Content-Type: image/png');
// 与 imagejpeg() 相比,使用 imagepng() 可产生更清晰的文本
imagepng($im);
imagedestroy($im);

PHP getimagesize函数和image_type_to_extension函数

获取图片尺寸
getimagesize($image_path)

Array(
    [0] => 256 //宽
    [1] => 256 //高
    [2] => 3   //IMAGETYPE常量,代表某种图片类型
    [3] => width="256" height="256"
    [bits] => 8
    [mime] => image/png
)


根据 getimagesize() 返回的 IMAGETYPE常量 获取图片类型(扩展名)
image_type_to_extension(IMAGETYPE常量)
没有匹配结果时返回 false

1: .gif
2: .jpeg
3: .png
4: .swf
5: .psd
6: .bmp
7: .tiff
8: .tiff
9: .jpc
10: .jp2
11: .jpx
12: .jb2
13: .swf
14: .iff
15: .bmp
16: .xbm
17: .ico
18: .webp

PHP try...catch无效的原因及解决办法

来源:百度文心一言

在PHP中,try-catch块主要用于捕获和处理异常(Exceptions),而不是用于捕获和处理警告(Warnings)或通知(Notices)。警告和通知是PHP的错误报告机制的一部分,它们指示代码中存在潜在的问题,但通常不会阻止脚本的执行。

如果你的PHP代码中的try-catch块看起来没有按预期工作,并且直接显示了警告(Warning),这通常意味着:

1. 抛出的不是异常:你的代码可能在try块中产生了警告,而不是抛出了一个异常。警告不会自动被catch块捕获。

2. 异常未被正确抛出:如果你预期某个函数或操作会抛出异常,但实际上它没有抛出(可能因为某些条件未满足),那么catch块也不会捕获任何内容。

解决方案

1. 检查错误类型:
确保在try块中发生的是异常(Exception)而不是警告(Warning)或通知(Notice)。
如果你想处理警告或通知,你可能需要调整PHP的错误报告级别,或者使用其他机制(如错误处理函数set_error_handler())来捕获这些错误。

2. 正确抛出异常:
确保在try块中的代码在遇到问题时能够抛出异常。
如果你的代码依赖于第三方库或框架中的函数来抛出异常,请确保该函数在失败时确实会抛出异常。

3. 使用错误处理函数:
如果需要捕获警告或通知,你可以使用set_error_handler()函数来设置一个自定义的错误处理函数。这个函数可以捕获错误,并可以根据需要抛出异常。

set_error_handler(function($severity, $message, $file, $line) {  
	if (!(error_reporting() & $severity)){  
		// This error code is not included in error_reporting  
		return;  
	}  
	throw new ErrorException($message, 0, $severity, $file, $line);  
});  
$arr=array('a');
try{  
	trim($arr);
}catch(Exception $e) {  
	echo var_export($e,true);
	echo $e->getMessage(), $e->getFile();
}	

4. 检查PHP错误报告设置:确保你的PHP配置(php.ini)或运行时配置中的错误报告设置符合你的需求。你可以通过error_reporting()函数来动态调整错误报告级别。


PHPQRCODE生成二维码

$data = 'i am qrcode';
$level = 'Q';// 纠错级别:L、M、Q、H
$size = 2;//元素尺寸
$margin = 5;//边距
$outfile = $path; //生成图片的路径,false直接输出到屏幕
$saveandprint = false;// true直接输出屏幕,false保存到文件中
$back_color = 0xFFFFFF;//白色底色
$fore_color = 0x000000;//黑色二维码色 若传参数要hexdec处理,如 $fore_color = str_replace('#','0x',$fore_color); $fore_color = hexdec('0xCCCCCC');
$QRcode = new QRcode();
//保存到文件
$QRcode->png($data, $outfile, $level, $size, $margin, false, $back_color, $fore_color);
//保存到文件并输出到屏幕
$QRcode->png($data, $outfile, $level, $size, $margin, true, $back_color, $fore_color);
//只输出到屏幕
$QRcode->png($data, false, $level, $size, $margin, false, $back_color, $fore_color);

imagecopy、imagecopymerge的区别

转自:https://www.jianshu.com/p/8023e25d9427

imagecopymerge 可以把不符合大小尺寸的图片压缩或拉伸成合适的水印大小,并对整个水印图片加透明度,但水印图片内部的透明度会被填充为默认黑色,例如带圆角的图片。

imagecopy 可以对原图素材裁剪,但不做压缩或填充。合成后保留png本身的透明度,例如圆角logo。

imagesavealpha 保存图像时是否保留完整的 alpha 通道信息(imagecopy不需要)
$img = imagecreatefromstring(file_get_contents($path));
imagealphablending($img, true);
imagesavealpha($img, true);

php采集、DOM操作

phpQuery
https://blog.csdn.net/summerxiachen/article/details/78681674
https://www.php.cn/faq/568108.html
http://code.google.com/p/phpquery/
http://phpquery-library.blogspot.com/

require_once './phpQuery.php';
phpQuery::newDocumentFile($url);
$title=pq('h1#activity-name')->text();
$author=pq("meta[name='author']")->attr('content');
$summary=pq("meta[name='description']")->attr('content');
$content=pq('div#js_content')->html();

QueryList 基于 phpQuery 实现
https://querylist.cc/
https://github.com/jae-jae/querylist

composer
https://www.phpcomposer.com/

composer中文文档
https://docs.phpcomposer.com/

php允许跨域设置

转自:https://www.yisu.com/zixun/604851.html

php设置允许跨域访问可以有三种方式,具体方法如下所示:

方式一:
header("Access-Control-Allow-Origin: *");//允许所有地址跨域请求

方式二:
header("Access-Control-Allow-Origin: http://localhost:8080");//指定某个地址可以跨域请求,这里只能指定一个

方式三:如果要允许多个地址跨域请求可以这样写

$origin = ['http://localhost:8080','http://localhost:8081'];
$AllowOrigin = 'http://localhost:8080';
if(in_array($_SERVER["HTTP_ORIGIN"],$origin)) {
    $AllowOrigin = $_SERVER["HTTP_ORIGIN"];
}
header("Access-Control-Allow-Origin: ".$AllowOrigin );

设置允许的请求方法,可以用*表示所有,header("Access-Control-Allow-Methods: POST");

如果允许请求携带cookie,此时 origin配置不能用 *,此时前端似乎也要做配置,让请求中携带cookieheader('Access-Control-Allow-Credentials:true');

设置允许跨域的请求头,通常会在请求头里面加登录验证信息,那么服务端需要指定允许那些请求头,这里不能用*,多个字段用逗号隔开。header('Access-Control-Allow-Headers:token');

PHP文件系统函数

  • basename — 返回路径中的文件名部分
  • chgrp — 改变文件所属的组
  • chmod — 改变文件模式
  • chown — 改变文件的所有者
  • clearstatcache — 清除文件状态缓存
  • copy — 拷贝文件
  • delete — 参见 unlink 或 unset
  • dirname — 返回路径中的目录部分
  • disk_free_space — 返回目录中的可用空间
  • disk_total_space — 返回一个目录的磁盘总大小
  • diskfreespace — disk_free_space 的别名
  • fclose — 关闭一个已打开的文件指针
  • fdatasync — Synchronizes data (but not meta-data) to the file
  • feof — 测试文件指针是否到了文件结束的位置
  • fflush — 将缓冲内容输出到文件
  • fgetc — 从文件指针中读取字符
  • fgetcsv — 从文件指针中读入一行并解析 CSV 字段
  • fgets — 从文件指针中读取一行
  • fgetss — 从文件指针中读取一行并过滤掉 HTML 标记
  • file_exists — 检查文件或目录是否存在
  • file_get_contents — 将整个文件读入一个字符串
  • file_put_contents — 将一个字符串写入文件
  • file — 把整个文件读入一个数组中
  • fileatime — 取得文件的上次访问时间
  • filectime — 取得文件的 inode 修改时间
  • filegroup — 取得文件的组
  • fileinode — 取得文件的 inode
  • filemtime — 取得文件修改时间
  • fileowner — 取得文件的所有者
  • fileperms — 取得文件的权限
  • filesize — 取得文件大小
  • filetype — 取得文件类型
  • flock — 轻便的咨询文件锁定
  • fnmatch — 用模式匹配文件名
  • fopen — 打开文件或者 URL
  • fpassthru — 输出文件指针处的所有剩余数据
  • fputcsv — 将行格式化为 CSV 并写入文件指针
  • fputs — fwrite 的别名
  • fread — 读取文件(可安全用于二进制文件)
  • fscanf — 从文件中格式化输入
  • fseek — 在文件指针中定位
  • fstat — 通过已打开的文件指针取得文件信息
  • fsync — Synchronizes changes to the file (including meta-data)
  • ftell — 返回文件指针读/写的位置
  • ftruncate — 将文件截断到给定的长度
  • fwrite — 写入文件(可安全用于二进制文件)
  • glob — 寻找与模式匹配的文件路径
  • is_dir — 判断给定文件名是否是一个目录
  • is_executable — 判断给定文件名是否可执行
  • is_file — 判断给定文件名是否为一个正常的文件
  • is_link — 判断给定文件名是否为一个符号连接
  • is_readable — 判断给定文件名是否可读
  • is_uploaded_file — 判断文件是否是通过 HTTP POST 上传的
  • is_writable — 判断给定的文件名是否可写
  • is_writeable — is_writable 的别名
  • lchgrp — 修改符号链接的所有组
  • lchown — 修改符号链接的所有者
  • link — 建立一个硬连接
  • linkinfo — 获取一个连接的信息
  • lstat — 给出一个文件或符号连接的信息
  • mkdir — 新建目录
  • move_uploaded_file — 将上传的文件移动到新位置
  • parse_ini_file — 解析一个配置文件
  • parse_ini_string — 解析配置字符串
  • pathinfo — 返回文件路径的信息
  • pclose — 关闭进程文件指针
  • popen — 打开进程文件指针
  • readfile — 输出文件
  • readlink — 返回符号连接指向的目标
  • realpath_cache_get — 获取真实目录缓存的详情
  • realpath_cache_size — 获取真实路径缓冲区的大小
  • realpath — 返回规范化的绝对路径名
  • rename — 重命名一个文件或目录
  • rewind — 倒回文件指针的位置
  • rmdir — 删除目录
  • set_file_buffer — stream_set_write_buffer 的别名
  • stat — 给出文件的信息
  • symlink — 建立符号连接
  • tempnam — 建立一个具有唯一文件名的文件
  • tmpfile — 建立一个临时文件
  • touch — 设定文件的访问和修改时间
  • umask — 改变当前的 umask
  • unlink — 删除文件
2026-01-08 星期四 农历冬月二十