前言
最近在系统的学习 PHP ,参考的资料是《PHP编程》+ 官方文档(如果你有好的学习资料,欢迎推荐给我)。虽然这本《PHP编程》是基于 PHP5 的,但我笔记里的代码,全部在 PHP 7.2 的环境里测试过,是能够运行的。另,本笔记中只记录我模糊不清的知识。
输出缓存
输出缓冲区
把输出的内容先放进内存,而不先显示。最根本的作用是,协调高速 CPU 和相对缓慢的 IO 设备(磁盘等)的运作。
函数
ob_start([callback])
: 打开输出缓冲。callback 参数是后处理输出的函数名。ob_get_length():int
: 获取当前缓冲区长度。缓冲没有开启返回 false 。ob_get_contents():string
: 获取当前缓冲区长度。缓冲没有开启返回 false 。ob_clean()
: 清理输出缓冲区但是不会关闭输出缓冲。ob_end_clean()
: 清理输出缓冲区并且结束输出缓冲ob_flush()
: 发送数据到网页服务器并且清理输出,但是不关闭输出缓冲。flush()
: 除了刷新和清理输出缓冲区,也会尝试让网页服务器立即发送数据到浏览器。ob_end_flush()
: 发送数据到网页服务器并且清理输出,并且关闭输出缓冲。错误处理
错误报告
PHP 中错误有三种等级:
提示: notice ,发生在执行脚本可能出现错误时,但正常执行时也遇到(例如,尝试访问一个不存在的变量)。
- 警告: warning ,表明一个非致命错误,典型的,警告在函数调用无效参数时就会显示。
- 错误: error ,表明致命状态,无法从脚本中恢复,解析错误是一个特殊的错误类型,在脚本中有语法错误时发生。除了解析错误外的所有错误都叫运行时错误
在 PHP 中可以在 php.ini
文件中用 error_reporting
选项全局修改这个特性。也可以在脚本中使用 error_reporting()
函数在本地变量错误报告行为。
错误抑制
可以通过在独立表达式前放置一个错误抑制符 @
来禁用它的错误信息.
$value = @(2 / 0);
错误抑制符不能抑制解析错误,只能抑制运行时错误的不同类型。
触发错误
可以在 PHP 中用 trigger_error()
函数抛出一个错误:
trigger_error(message [, tyep="E_SUER_NOTICE"]);
type 参数:
* E_USER_ERROR : 错误
* E_USER_WARNING : 警告
* E_USER_NOTICE : 提示
定义错误处理器
如果你想格式化错误信息,可以向 PHP 提供错误处理器。基本方法是创建一个错误处理函数并用 set_error_handler()
来注册。
声明的函数可以接受 2 到 5 个参数。前两个参数是错误代码和错误描述。后面三个参数分别是:错误发生的文件名、错误发生的行号和错误发生的符号表复制。
function displayError($error, $errorString, $filename, $line, $symbols)
{
echo "<p>Error '<b>{$errorString}</b>' occurred.<br />";
echo "-- in file '<i>{$filename}</i>', line $line.";
}
set_error_handler('displayError');
$value = 4 / 0;
//输出
/*
Error 'Division by zero' occurred.
-- in file 'C:\Git\php\text1.php', line 8.
*/
错误处理器中的日志
PHP 提供内建函数 error_log()
,把错误记录到管理员放错误日志的地方。
error_log(message, type [, destination [, extra_haders ]]);
type参数:
* 0 : 用 PHP 标准错误日志
* 1 : 把错误邮件给 destination 地址
* 3 : 附加错误到 destination 文件
当类型为 0 来调用 error_log()
。通过改变 php.ini
文件中 error_log
的值,可以修改要往那个文件中写日志。如果将其设置为 syslog
,系统日志将被使用。
性能调优
一旦你的代码可以工作,就可以优化代码。优化代码的目标通常为缩短运行时间和减少内存占用。
分析
使用 microtime()
来准确的标识消逝的时间。
例如,下面代码可以的得到 phpinfo()
输出花费了多少时间:
ob_start();
$start = microtime();
phpinfo();
$end = microtime();
ob_end_clean();
echo "phpinfo() took" . ($end - $start) . "seconds to run.\n";
优化执行时间
- 避免使用
printf()
,只用echo
。
- 避免在循环中重新计算值,因为 PHP 解析器不会移除循环不变量
// 如果 $array 大小不变
for($i = 0; $i < count($array); $i++) // bad
$num = count($array);
for($i = 0; $i < $num; $i++) // good
- 只包含必要的文件。分离出包含文件中确定要用的函数,将他们放在一起。
- 如果用了数据库,要使用持久化数据库连接——启动和关闭数据库连接时比较慢的。
- 当可以用简单字符串操作函数时就不要用正则表达式。
优化内存占用
- 用数字代替字符串
for($i = "0", $i < "10"; $i++) // bad
for($i = 0; $i < 10; $i++) // good
- 当你处理完了一个大字符串,把保存字符串的变量设置为空,这会释放内存以便重用。
- 只包含必需的文件,用
include_once
和require_once
来替代include
和require
。
- 处理完 MySQL 和其他数据库的结果集后立即释放。在内存中保存使用后的结果集没有任何好处。
扩展流量的三种方式:
反向代理缓存
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。代理用来更快的提供静态文件。
负载均衡
负载均衡是分摊负载到几台机器上。一个“负载均衡系统”通过均衡分布负载或转发请求到较少负载的机器上实现。
数据库复制
有时数据库服务器会成为瓶颈——很多并发查询可能会拖垮一个服务器。复制是一个很好的解决方案。把发生在一个数据库上的所有同步带到其他一个或多个数据库上,这可以让你查询分散到不同的数据库服务器而不是自从一台服务器加载。
最有效的模型是单向复制,就是你只有一个主数据库要复制到几个从数据库上。写数据库到主数据库,读数据库是负载均衡地跨多个从库。这个技术的目标架构是多读小写。
感谢你看到了这里。如果文章有错误,请评论指正,谢谢!