PHP引导的更好方法是什么?

3

您好,以下是关于是否在PHP应用程序中使用引导程序的最佳实践。我发现有两种方法可以引导我的PHP应用程序。需要一些建议哪种方法更好。

第一种方法:
为文件夹结构定义一个常量

$controllerPath = 'controller';
define('CONTROLLER', str_replace('\\', '/', realpath($controllerPath)).'/');

//usage
require_once CONTROLLER . 'somecontroller.php';

第二步
使用ini_set将包含路径设置为应用程序根目录。

$rootPath = $_SERVER['DOCUMENT_ROOT'];
$includePath = ini_get('include_path');
ini_set('include_path', '.'.PATH_SEPARATOR.$rootPath.PATH_SEPARATOR.$includePath);

//usage
require_once 'controller/somecontroller.php';

请告诉我哪种方式更好。
对于高负载应用程序,哪种方法最好?
5个回答

4
使用ini_set将其设置为应用程序上方的目录。这样,您就可以在require语句中使用字面字符串。此外,它使重用代码更加容易。
require 'coolapp/class/Model.php'
require 'coolapp/display/Router.php'
require 'spinoff/display/JsView.php'
// etc

这类似于Java中具有完全限定导入的想法com.whatever.app.more,或者在Python中,所有应用程序的导入都应该是相对于该应用程序的绝对路径。

关于高负载应用程序

除非您正在加载数千个文件,否则包含文件所需的时间可能不是瓶颈。 但是,如果情况是如此,您有几个选择。 其中之一是APC,它将include的结果缓存在内存中。 另一种方法是从单个文件加载所有内容,类似于将JavaScript文件合并为一个以获取更好的性能(巧合的是,APC具有提供此信息的功能)。 安装APC非常简单,并且完全透明,可获得约50%更好的性能提升。


3

最好使用绝对路径,而不是让PHP在给定的包含路径中查找文件。

因此,我倾向于使用第一种方法,即使用一个常量来保存应用程序根目录的绝对路径。


1
这是我所做的事情:
  • 在您的文档根目录(或任何您想要命名的位置)中放置一个/include目录,用于存放所有类、帮助函数等;
  • 使用mod_rewrite使/include目录不被提供服务;
  • 其中有一个名为setup.php的文件,该文件设置相关的ini参数、路径等;
  • 每个页面都通过相对路径包含该文件;以及
  • 其他所有内容都可以依赖于它创建的设置。

顶级.htaccess的示例重写规则:

RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /include/
RewriteRule ^include/ - [R=404,L]

我可能有些偏差。 我手头没有我的标准规则。 你会注意到我创建的是404错误而不是403(禁止)。 这是故意的。 当您登录系统时,它不会说“未知用户”或“密码不正确”,因为那会告诉您一些信息。 我宁愿假装根本没有/include目录,而不是说它存在,但您只是不能查看它。

在那时,您可以设置所有需要的内容,以便您的其余代码可以执行:

require 'Class.php';

或者甚至定义一个__autoload(),这样它就会自动发生。


1

这是我的引导程序加载器的示例:

if (!defined('APPLICATION_PATH')) {
    define('APPLICATION_PATH', realpath(getcwd() . '/../application'));
}

/**
 * Add the APPLICATION_PATH and the library dir to the include_path
 */
set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . PATH_SEPARATOR . realpath(APPLICATION_PATH . '/../library'));

/**
 * Load the file loader to setup the class autoloader
 */
include_once 'Loader.php';
if (!class_exists('Loader')) {
    die('Could not load class loader.');
}

spl_autoload_register('Loader::autoload');

我个人会选择第二种方式。我已经学会了喜欢使用include_path:从许多目录中查找可能会有一些性能损失,但我怀疑它不会很显著。它还可以防止因忘记包含路径常量而导致的错误。

顺便说一下,我将我的控制器等放在/application/中,并在/library/中放置一些库。这些都在网站根目录之上。这完全防止用户访问这些文件,否则您必须采取预防措施来防止这种情况发生。如果您的主机支持此功能(某些共享主机不支持),请利用它!

更新

在高负载应用程序的情况下,选择第二种方法是否好?

在我看来,如果您密切关注include_path中的内容(例如,在我的Windows开发机上,我有许多不需要的内容:SQL Server、Ruby等),并剥离掉任何不需要的内容,那么第二种方法就可以了。

另一件事是,在脚本末尾转储include_path,并将其硬编码到您的php.ini文件中。

实际上,我认为这不会成为您系统性能的瓶颈。使用对您来说更容易的方法。

您是否在运行网站时遇到性能问题,还是这只是预防性措施?我可以理解您想要进行预优化(我必须停止自己),但是认真考虑一下。当出现这些问题时再处理它们。当您处于拥有受欢迎网站的幸运位置时,请处理它们。最终,如果您需要替换一些require,这并不是一场噩梦。


是的,还有一件事:如果你使用的是PHP5(应该是的),自动加载类(无需使用require,只需实例化类)是一个非常有用的工具。http://www.php.net/autoload - Ross
这只是一项预防措施。但是该应用程序很大,因此我不仅需要几个'require_one',这对我来说将是一场噩梦 :) - Zaje
我建议你无论如何都要看autoload。这意味着类是按照它们被使用的顺序加载的。你可能需要使用一些命名约定,但我通常使用目录结构。例如,Zend_Form = Zend/Form.php。 - Ross

0

我更喜欢第二种方式 - 在一个大型的PHP项目中使用它,非常享受。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接