接近动态 php 包括在没有前端控制器的遗留项目上
Posted
技术标签:
【中文标题】接近动态 php 包括在没有前端控制器的遗留项目上【英文标题】:Approaching dynamic php includes on legacy projects without a front controller 【发布时间】:2015-01-11 05:35:00 【问题描述】:在 php 中通过 Include
s/require_once
s 进行依赖管理是一件很痛苦的事情。每隔一段时间,我就会改变一些东西,而且东西会中断,我必须重新考虑我在 php.ini 中初始化第一个 include()/require() 的方法。我觉得我缺少一种更强大的技术来解决我所有的问题,但我似乎还没有找到它。
使用 mvc 自动加载会很好!但对于遗留程序项目,我认为这没有帮助?
过去的方法
可能和其他人一样,我从相对路径开始。 require_once('../../../core/core.php');
例如。不幸的是,当您开始需要具有自己所需依赖项的库时,就会中断。因此,我转而使用动态包含,该包含从层次结构中的任何位置解析出主项目文件夹:require_once(substr(dirname(__FILE__), 0, strpos(dirname(__FILE__), 'my_project')+8).'core/database/admin.database.connection.php');
这意味着我可以在适当的权限的任何位置传递它,并将其移动到项目中的任何位置它仍然可以工作!不幸的是,当我实现 CI 并且 CI 项目设置了一个项目根目录时,它坏了:/home/rof/bitbucket.org/repo_name/clone/
它不包含特定的字符串“my_project”,因此破坏了所有包含。所以在过去的一个小时左右,我一直在修复包含,这并不好玩。我想找到一个“最终解决方案”。
目前使用
目前我一直在将包含更改为:
require_once(realpath(__DIR__.'/../../').'/core/database/admin.database.connection.php');
不幸的是,如果我将一组脚本向上或向下移动一个目录(例如将 users/orders/ 移动到 admin/orders 或所有各种内务管理方法),这将需要再次重写每个单独的脚本。将 DIR.'/../../' 更改为 DIR.'/../../../' 或其他。这很糟糕,因为它非常复杂,以至于尝试在项目或目录范围内重写它是可怕的,东西可能会坏掉。
我的目标
第一个简单性,我想设置包含并确定它们会 工作并忘记他们。 第二层系统,以便不同区域 可以包含具有不同访问级别的库 3rd 我不想在事情发生变化时重写包含。理想情况下,我愿意 将包含内容写在一个地方供管理员访问,一个地方供用户使用 访问,一个公共访问的地方。对于非面向对象、基于过程/函数、目录结构复杂的php项目,最终的解决方案是什么?
示例目录结构和脚本
这是一个几乎真实的目录结构,非常标准,但只是为了给你一个想法:
core/
- core.php
- environment.php
- database/
- database.php
- admin.database.connection.php
- user.database.connection.php
- public.database.connection.php
www/
- index.php
- contactus.php
- map.php
- ...
- users/
- login.php
- logout.php
- accountdetails.php
- ...
- admin/
- login.php
- logout.php
- index.php
- admin.php
...
- reports/
- revenue_report.php
- orders.php
- clientslist.php
- orders/
- orderslist.php
- orderview.php
...
希望您明白这个想法,一个带有过程代码、许多复杂脚本和多层数据库访问的旧遗留系统。
【问题讨论】:
【参考方案1】:无论程序设计如何,您都必须有一些通用文件,例如带有您的数据库连接信息的config.php
。
所以你可以在那里设置一些定义:
首先,您的应用的基本路径,相对于配置文件...
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../'); // or whatever
注意,从 PHP 5.3 开始,您可以使用 __DIR__
代替 dirname(__FILE__)
然后您可以为每组文件设置单独的定义。也许:
define('CORE_PATH', APPLICATION_PATH . '/core/');
然后在您的个人脚本中,您可以这样做
include(CORE_PATH . 'database/admin.database.connection.php');
或者,如果您想对其进行微调,请改为为 /core/database/
定义路径,然后执行例如include(CORE_DATABASE_PATH . '/admin.database.connection.php');
如果你移动这些文件夹,你只需要更新你的配置文件。
【讨论】:
当然,我确实为各种事物定义了路径配置,但它们只有在首先包含在任何脚本中之后才可用,这是问题区域。我会在我的问题中澄清。 啊,那么也许您可以在初始包含路径中使用 $_SERVER['DOCUMENT_ROOT'] 例如include($_SERVER['DOCUMENT_ROOT'] . '/../config.php')
在每个文件的开头还是什么?【参考方案2】:
我现在已经处理过很多此类问题,以下是我在所有情况下强烈建议的内容:尽快通过前端控制器路由所有内容!
在 php 中创建一个前端控制器并通过它处理所有脚本是非常有益的,只要您可以设置它。如果你还有像example.php
这样的遗留脚本,让你的前端控制器index.php
将它们列入白名单!因此,像 mydomain.com/example 这样的 url 将通过前端控制器进行路由,获取所有基本包含,然后只有在列入白名单时才包含 example.php
脚本!
其他任何事情都只是推迟了统一一个包含许多微小分离脚本的破碎代码库的不可避免的问题。
【讨论】:
以上是关于接近动态 php 包括在没有前端控制器的遗留项目上的主要内容,如果未能解决你的问题,请参考以下文章