一个类有几千行,拆分其中的一部分封装成一个单独的类(这里一个类一个文件),通过引入这个类文件,减少原代码的行数,增加代码可读性和可维护性。
这里有两个疑虑:
一、引入外部的类文件,用PHP那个方法include, require?
二、引入外部类,然后再实例化,性能损耗如何?
重要说明:包含外部文件路径设置,以及include_path是如何起作用可见鸟哥博客风雪之隅:深入理解PHP之require/include顺序
设置include_path
php.ini中可参考手册这里。
include_path=".:/php/includes"
php-fpm.conf中
php_admin_value[include_path] = ".:/usr/local/sinasrv2/lib/php"
PHP代码中参考手册这里。
set_include_path('/usr/lib/pear'); // 或使用 ini_set ini_set('include_path', '/usr/lib/pear');
一、引入外部文件用那个方法
我们知道PHP包含并运行外部文件有4个语句结构,include、require、include_once、require_once。include(require)_once直接忽视,就当不存在,原因可见文末的使用原则。
这里主要整理include和require的区别:
0、找不到指定的文件,include语句结构提示warning并继续运行,require语句结构提示error并停止运行(这也是官网文档唯一说明的区别)。
echo 'start: ' . PHP_EOL; include '/home/test.php'; // warning // require '/home/test.php'; // error echo 'end' . PHP_EOL;
1、include和require都是有条件包含, include和require都不会在程序执行前去加载文件, 都是在执行到的时候去加载文件。
time.php中定义了变量$time。
date_default_timezone_set('Asia/Shanghai'); $time = date('Y-m-d H:i:s');
time2.php中定义变量$time2。
date_default_timezone_set('Asia/Shanghai'); $time2 = date('Y-m-d H:i:s');
以下代码require并没有执行
echo 'start: ' . PHP_EOL; if (true) { include 'time.php'; } else { require 'time2.php'; } var_dump($time, $time2, 200); // "2018-10-08 23:02:08" NULL 200 echo 'end' . PHP_EOL;die;
(php5.6.30和php7.0.22输出一致)
2、不能证明两者的如下差异,include执行时文件每次都要进行读取和评估,而require文件内容替换了语句本身只处理一次。
3、其他语言引入外部文件
Java引入外部包通过import
Python引入外部文件
假设以下两个python文件在同一个目录下
hello.py
world.py
在hello.py中通过import world就可以使用world.py中函数
Lua引入外部文件
通过require函数来引入其他模块
local cjson = require 'cjson'
Golang引入外部包
// 单个包 import "fmt" // 多个包 import ( "net/http" "testing" "funnel/tasks" "github.com/jame2981/rhombus" )
二、引用外部类性能损耗
不使用外部类的case:
echo 'start:' . PHP_EOL; $stime = microtime(true); function task() { for ($i = 0; $i < 10; $i++) { sleep(1); } return true; } $do_res = task(); var_dump($do_res); $etime = microtime(true); $internal_time = round(($etime - $stime) , 3); var_dump($internal_time, 200); echo 'end:' . PHP_EOL;
使用外部类的case(把函数task()封装到Job类中):
class Job { function task() { for ($i = 0; $i < 10; $i++) { echo $i . PHP_EOL; sleep(1); } return true; } }
调用Job类中的成员方法task()
echo 'start:' . PHP_EOL; $stime = microtime(true); include './Job.php'; $obj = new Job(); $do_res = $obj->task(); var_dump($do_res); $etime = microtime(true); $internal_time = round(($etime - $stime) , 3); var_dump($internal_time, 200); echo 'end:' . PHP_EOL;
以上两种方式,在PHP5.6和PHP7.0下执行结果平均时间都在10.036s左右。【对比include和require引入Job.php,执行时间差异不明显】
注:高并发下的执行情况还有待测试。
三、总结自己使用include(require)原则
0、用控制语句的方式使用include(require), 不使用函数的方式。(虽然支持函数的方式,知道就好,不使用)
include $_SERVER['DOCUMENT_ROOT'] . '/lib/sample.lib.php';
1、不使用include(require)_once。原因见鸟哥博客。
2、引入的文件如果影响全局就用require, 如果是局部就用include。
3、如果没有条件限制引入文件include(require)就放在程序开始行,否则放在条件中。
参考:
http://cn2.php.net/manual/zh/function.include.php
http://www.laruence.com/2012/09/12/2765.html
https://segmentfault.com/a/1190000005030675