这篇文章上次修改于 1509 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

近期我入了台阿里云国内 VPS 服务器,也同时买了个域名进行了备案。备案过后,当然是要先体验一波国内服务器的速度提升啦!

我的小窝一直部署在远在美国洛杉矶的服务器,总有人反应这个站极卡无比(我这其实多数时间都蛮快的)于是这就是我的第一个测试对象了。由于新环境内存比较大,因此我部署了 Windows 系统,同时采用 IIS 管理网络服务。

解决 URL 重写

要知道我的程序路由经过定制,不是简简单单的 GET 参数实现的,这种路由必须启用 URL 重写功能才能正常访问。一番搜索后,我用了 ThinkPHP 的 URL 重写代码,经过测试后和我的项目是通用的,在此也分享一波。

<rules>
    <rule name="OrgPage" stopProcessing="true">
        <match url="^(.*)$" />
            <conditions logicalGrouping="MatchAll">
                <add input="{HTTP_HOST}" pattern="^(.*)$" />
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}” matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="index.php/{R:1}" />
        </rule>
    </rules>
</rewrite>

修改 PHP 错误级别

PHP 推荐我在开发的情况下使用 E_ALL 作为错误提示级别,但要知道使用这种方式的话,只要一个变量在不存在的情况下被赋值到另一个变量,就会导致程序终止,可以说是非常严格了。然而这并不是我喜欢的模式,如果要避免这样的终止,则必须要多写很多判断代码,降低执行效率。

; error_reporting
;   Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
;   Development Value: E_ALL
;   Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT

经过实测,最适合我项目的模式是 E_ALL & ~E_NOTICE 模式。将这个 error_reporting 值修改到 php.ini 上就可以了。

解决数据库内容乱码

我的小窝代码总算是可以正常执行,可以访问了,但又遇到了一个新的问题,就是我页面的部分内容出现了乱码。而这些内容都是从 MySQL/MariaDB 上获取的,因此主要可以从“数据库编码”和“数据库配置”两个方面上去着重检查。

打开 phpMyAdmin 登录连接数据库,我查了下数据库及各个表的编码设置,均为 utf8mb4_general_ci 形式,而且里面的数据都是正常显示的。这么一排查,基本可以确认是连接配置的问题了。

我的代码都是原封不动的复制过来的,没做任何变动。会不会是 MySQL 有配置文件的变量是用于设置默认编码的呢?我打开了 phpMyAdmin 的变量面板,发现有很多变量的默认设定是拉丁文(改了 character set client character set results 等等各种变量,但均无效果)

继续往下翻,我注意到了一个名为 init connect 的变量,这个是指连接登录数据库时首先执行的 SQL 语句?对比了一下原来机器上的设置,还确实在这里有所差异!当我把值改为 SET NAMES utf8mb4 之后,一切都恢复正常了!

解决 CURL 报错

本以为一切都正常的我,自信的将每一个页面都翻了一遍,发现歌单页的排行榜获取失败,且无输出任何报错信息。这就很纳闷了,由于这个服务器目前就是拿来调试拿来玩的,那就在代码上多加些 var_dump() 输出几次变量检查检查?

可万万没有想到的是,无论我怎么 Dump,怎么 Echo,这 PHP 就是屁都不放一个。只说我取得数据后的 foreach 函数引用了一个无法遍历的对象(都没获取成功,怎么可以遍历?)

我仔细观察了一波后发现,这 PHP 的报错信息怎么和我洛杉矶服务器的格式不太一样?于是我写了一段测试代码,专门创造了一个无法遍历的 foreach,在它前面也一样写了很多 var_dumpecho 语句。将它分别传到两台服务器对比测试,果然有问题!

<?php

echo "Testing";

var_dump("FXXK");

foreach($file["result"] as $item => $value){
    echo $value;
}

不同的报错信息.jpg

这样的问题确实让我感到棘手,写了这么久的 PHP,从来没遇到过这么奇葩的问题。可 PHP 主要也就是配置 php.ini 这个文件,于是我将怀疑目标始终定在了它上面。

【解决过程】

既然 foreach 无法遍历,那么基本可以确定是 Curl 出问题了。一番搜索后得知,用 curl_error() 函数可以获取对应 Curl 请求中的错误信息,将它插入到 curl_exec()var_dump(),确实得到了一段错误信息。

SSL certificate problem: unable to get local issuer certificate

搜索了一波后,得知其主要原因是 php.ini 配置文件少了一个证书的引用,导致无法访问任何 HTTPS 请求。下载一个塞进去引用,完美解决。

参考:http://blog.sina.com.cn/s/blog_150e503430102yiqh.html