前言
路径分隔符不同导致的问题
Windows 系统的路径分隔符为反斜杠(\),而 Linux 系统是正斜杠(/),当代码中使用了 PHP 自带函数获取路径,再进行路径拼接的话就会出现这种结果:D:\A\B/C/D.jpg,这并没有什么问题,PHP 可以正常处理。但如果对这一路径字符串进行替换、比较等操作,就会出现问题,因为D:\A\B/C/D.jpg和D:/A/B/C/D.jpg并不相等,但他们指向的是同一个文件。
在 Chevereto 3.20+ 版本中,此问题会导致上传用户头像后卡住,在 4.0+ 版本中,还会导致网站无法正常加载静态资源。修复很简单,将路径字符串中的反斜杠(\)全部替换成正斜杠(/)即可。
Chevereto 3.20.X 版本:/app/lib/classes/class.localstorage.php:62
Chevereto 4.2.X 版本:/app/src/Legacy/Classes/LocalStorage.php:62
在
$target_filename = str_replace('/.\/', '/', $target_filename);前添加一行
$target_filename = str_replace('\\', '/', $target_filename);即可解决上传头像后卡住问题。
Chevereto 4.2.X 版本:/app/src/Legacy/functions.php:1054
将
define('PATH_PUBLIC', dirname(__DIR__, 3) . '/');改为
define('PATH_PUBLIC', str_replace('\\', '/', dirname(__DIR__, 3)) . '/');Chevereto 4.2.X 版本:/app/src/Legacy/functions.php:1135
将
dirname($script_name)改为
str_replace('\\', '/', dirname($script_name))Chevereto 4.2.X 版本:/app/legacy/entrypoints/index.php:26
将
dirname($scriptName)改为
str_replace('\\', '/', dirname($scriptName))即可解决静态资源加载问题。
Intervention Image 与 Windows 的兼容性问题
Intervention Image 的 save 方法在 Windows 下必须使用图片扩展名,而 Chevereto 在图片上传处理中全程使用tempnam()函数生成的 .tmp 文件,在用到 save 方法时就会出错。
修复这个问题我用了个简单的方法,save 时加上原图片扩展名,即存为 .tmp.xxx 文件,再将 .tmp.xxx 文件 rename 回 .tmp 文件。
以下更改仅供参考,如需使用请看清区别,并做好备份。
Chevereto 3.20.X 版本:/app/lib/classes/class.upload.php:160
Chevereto 4.2.X 版本:/app/src/Legacy/Classes/Upload.php:237
将
if (array_key_exists('exif', $this->options)) {
    $this->source_image_exif = null;
    try {
        $this->source_image_exif = \exif_read_data($this->downstream);
    } catch (Throwable $e) {
    }
    if (isset($this->source_image_exif)) {
        $this->source_image_exif['FileName'] = $this->source_filename;
        if (isset($this->source_image_exif['Orientation'])) {
            ImageManagerStatic::make($this->downstream)->orientate()->save();
        }
    }
    if (!$this->options['exif']) {
        unset($this->source_image_exif);
        if (ImageManagerStatic::getManager()->config['driver'] === 'imagick') {
            $img = ImageManagerStatic::make($this->downstream);
            $img->getCore()->stripImage();
            $img->save();
        } else {
            $img = @imagecreatefromjpeg($this->downstream);
            if ($img) {
                imagejpeg($img, $this->downstream, 90);
                imagedestroy($img);
            } else {
                throw new UploadException("GD: Unable to create a new JPEG without Exif data", 444);
            }
        }
    }
}改为
if (array_key_exists('exif', $this->options)) {
    $this->source_image_exif = null;
    $tmp_name_img = $this->downstream . '.' . $this->extension; // edited
    try {
        $this->source_image_exif = \exif_read_data($this->downstream);
    } catch (Throwable $e) {
    }
    if (isset($this->source_image_exif)) {
        $this->source_image_exif['FileName'] = $this->source_filename;
        if (isset($this->source_image_exif['Orientation'])) {
            ImageManagerStatic::make($this->downstream)->orientate()->save($tmp_name_img); // edited
            $renamed = rename($tmp_name_img, $this->downstream); // edited
        }
    }
    if (!$this->options['exif']) {
        unset($this->source_image_exif);
        if (ImageManagerStatic::getManager()->config['driver'] === 'imagick') {
            $img = ImageManagerStatic::make($this->downstream);
            $img->getCore()->stripImage();
            $img->save($tmp_name_img); // edited
            $renamed = rename($tmp_name_img, $this->downstream); // edited
        } else {
            $img = @imagecreatefromjpeg($this->downstream);
            if ($img) {
                imagejpeg($img, $this->downstream, 90);
                imagedestroy($img);
            } else {
                throw new Exception("Unable to create a new JPEG without Exif data", 644);
            }
        }
    }
}即可。
Chevereto 3.20.X 版本:/app/lib/classes/class.imageconvert.php:29
Chevereto 4.2.X 版本:/app/src/Legacy/Classes/ImageConvert.php:26改写法了,看着改就行。
将
public function __construct($source, $to, $destination, $quality=90)
{
    if(!in_array($to, ['jpg', 'gif', 'png'])) {
        return $source;
    }
    $image = ImageManagerStatic::make($source);
    $image->encode($to, $quality)->save($destination);
    $this->out = $destination;
}改为
public function __construct($source, $to, $destination, $quality=90)
{
    if(!in_array($to, ['jpg', 'gif', 'png'])) {
        return $source;
    }
    $source_img = $destination . '.' . $to; // edited
    $image = ImageManagerStatic::make($source);
    $image->encode($to, $quality)->save($source_img); // edited
    $renamed = rename($source_img, $destination); // edited
    $this->out = $destination;
}即可。
启用“图片/相册 URL 地址 SEO 优化”功能后含有中文的链接重定向次数过多问题
这个问题只有 IIS 用户会出现,由两个因素导致,一是 IIS Rewrite 中文系统会使用 GBK 编码,二是 IIS Rewrite 后 $_SERVER['REQUEST_URI'] 获取到的是 urldecode 后的值。
Chevereto 4.2.X 版本:/app/src/Legacy/G/functions.php:1163
在
new ServerVar(array_merge($envDefault, $env, $_server));之前添加一段
// For Windows IIS URL Rewrite
if (isset($_server['REQUEST_URI']) && mb_check_encoding($req_uri = $_server['REQUEST_URI'], 'GBK')) {
    $_server['REQUEST_URI'] = mb_convert_encoding($req_uri, 'UTF-8', 'GBK');
}或者不使用这段代码,在系统区域设置中启用 “Beta 版:使用 Unicode UTF-8 提供全球语言支持。”。
Chevereto 4.2.X 版本:app\legacy\routes\album.php:96
将
if (! starts_with($album['url'], get_public_url(get_current_url()))) {改为
if (! starts_with(rawurldecode($album['url']), get_public_url(get_current_url()))) {Chevereto 4.2.X 版本:app\legacy\routes\image.php:102
将
if ($image['path_viewer'] != get_current_url(true, ['lang'])) {改为
if (rawurldecode($image['path_viewer']) != get_current_url(true, ['lang'])) {其他问题
待发现。欢迎留言探讨。
好多年没来过了-。-
想你了牢白
666