在php中创建类库-如何处理库根位置?

在php中创建类库-如何处理库根位置?,php,Php,我将在php中创建一组相互关联的类。现在我想包括使用绝对路径的文件,即 如果我在 '/com/mysite/licences/Generator.class.php' 我希望包括以下文件: include '/com/mysite/lib/Utils.class.php' include '/com.mysite.setup.inc.php'; 我不想包括这样的内容,我认为这是令人困惑和丑陋的 include '../licenses/Utils.class.php' 除非'com'不在

我将在php中创建一组相互关联的类。现在我想包括使用绝对路径的文件,即

如果我在

'/com/mysite/licences/Generator.class.php'
我希望包括以下文件:

include '/com/mysite/lib/Utils.class.php'
include '/com.mysite.setup.inc.php';
想包括这样的内容,我认为这是令人困惑和丑陋的

include '../licenses/Utils.class.php'
除非'com'不在public_html的根目录中,否则它可以正常工作。我假设我需要某种前缀来附加到每个文件库的根目录中,这些根目录在当前文件系统中保存“com”的位置。所以看起来可能是这样的

include LIBRARY_ROOT.'com/mysite/lib/Utils.class.php'
最好的方法是什么

-----------------我的解决方案---------------- 更新: 看起来这个解决方案也不起作用,因为set_include_path('/');似乎在关闭php标记处重置?>而不是包含文件中的标记


这就是我所做的

在文件系统的根目录中创建了一个名为的文件,如下所示

com.mysite.setup.inc.php

长名称是包名称的Java格式,这样有助于防止命名冲突。如果我将其命名为setup.php,则根文件夹中的另一个文件也可能被命名为setup.php

com.mysite.setup.inc.php包含以下内容:

<?php
/**
 * Setup file for each class
 */

//Path
set_include_path('/');

//Other common setup

?>
如果库被移动,您所要做的就是更新com.mysite.setup.inc.php以反映更改

我们得到的是一个干净的命名约定,不需要在每个包含中附加难看的前缀。我们现在可以在任何类文件中包含这样的内容

include '/com.mysite.setup.inc.php';
include 'com/mysite/lib/Utils.class.php';
include 'com/mysite/lib/text_utilities/Text.class.php';
include 'com/mysite/encryption/Cipher.class.php';

class MyClass {.......
只是

包括

include LIBROOT. 'lib/Utils.class.php';

$Server [文件记录根]将在99%种情况下工作。

您可以选择考虑将该库设置为您的库基础目录,并且只包括(“LIb/UTIL.class .php”)。当涉及到目录分隔符时,您可能还需要注意跨平台兼容性。Windows通常不太挑剔,可以接受反斜杠和正斜杠,但在其他操作系统上情况往往不是这样

您可以从脚本的文件名派生库根路径。选择一个脚本,其路径相对于库将保持不变。我通常有一个脚本(称为constants.php),我在应用程序开始时就调用它。它定义了应用程序中使用的一系列常量

在此基础上,我使用SCRIPT_FILENAME派生到库文件的路径。这种方法意味着您可以在文件系统上移动脚本,或者将脚本移动到另一个文件系统,它们仍然可以解析正确的路径。我已经包含了一个快速且脏的函数,它可以分解一个或多个路径,然后使用正确的操作系统目录分隔符重新组合它们:

在constants.php中:

define(
    'MY_LIB',
    combine_path(
        dirname($_SERVER['SCRIPT_FILENAME']),
        'lib/my_lib'
    )
);

define(
    'THIRD_PARTY_LIB',
    combine_path(
        dirname($_SERVER['SCRIPT_FILENAME']),
        'lib/third_party_lib'
    )
);

function combine_path() {
    // Get an array of function arguments.
    $args = func_get_args();

    // Prepare an array to hold the list of path nodes.
    $path = array();

    // Process each argument.
    foreach ($args as $arg) {
        // Split the path at backslash or forward slash separators.
        $nodes = preg_split('/[\\/\\\]/', $arg);

        // Push each node onto the end of the path array.
        foreach ($nodes as $node) {
            $path[] = $node;
        }
    }

    // Join the path nodes with the system's directory separator.
    return implode(DIRECTORY_SEPARATOR, $path);
}

您应该使用autoload函数,在autoload中,在循环中不断增加一个dir,直到找到lib dir,然后将路径附加到您要查找的类文件中

差不多

<?php
function __autoload( $className ){
// where all your classes are. 
//you can add logic for namespaces fairly easily here as well
$classDir = "lib"; 
// the path to your library we wil modify this in the loop
$pathPrefix = '';

while( !is_dir( $pathPrefix . $classDir )){
    $pathPrefix .= '../';
}

if( file_exists( $pathPrefix . $classDir . DIRECTORY_SEPARATOR . $className . 'php' )){
    include( $pathPrefix . $classDir . DIRECTORY_SEPARATOR . $className . 'php' );
}else{
    throw new Exception( $className . ' could not be found by autoload' );
}

如果我在'com'setIncludePath.php根目录下的文件中添加了set_include_path指令。然后我会简单地把它放在我所有课程的最上面,然后再把其他内容放进去,我的想法正确吗?事实上,我刚刚意识到,即使我设置了包含路径,仍然无法知道包含路径是什么。它可以手动更改,但我只想更改一次。不是每个文件都有。因此,即使我包含该文件,我也会让“相对”(../../../../../../../../../../)转到com并包含该文件。每个文件都需要一个不同的相对路径,这取决于它所在的位置。您更新的解决方案看起来差不多正确。这正是PHPs include_path的目的。顺便说一句,你读过关于自动加载的文章吗?每当一个类被实例化时,这个神奇的方法就可以加载单个的类脚本。如果您的每个类文件都对应于一个实际的类,则可能会省去所有手动include调用(mysite.setup.inc.php除外)。如果使用此解决方案,则必须将path/com硬编码到每个类中,如果在某个阶段我移动了库呢?你应该在你的include链中使用的一个公共文件中定义它,我想我解决了这个问题。你认为上面的解决方案怎么样?(更新了问题)我认为您的解决方案会起作用,但如果情况发生变化,仍然需要手动编辑路径。如果您的应用程序部署到一个共享托管环境中,而您没有访问根目录的权限,那么这也会变得更加困难。如果定义了相对于已知位置(运行脚本的位置)的路径,则可以避免此问题。当然,您可以将此路径添加到include路径。您可能还想检查类()的自动加载,因为这可以减少需要进行的包含的数量。
<?php
function __autoload( $className ){
// where all your classes are. 
//you can add logic for namespaces fairly easily here as well
$classDir = "lib"; 
// the path to your library we wil modify this in the loop
$pathPrefix = '';

while( !is_dir( $pathPrefix . $classDir )){
    $pathPrefix .= '../';
}

if( file_exists( $pathPrefix . $classDir . DIRECTORY_SEPARATOR . $className . 'php' )){
    include( $pathPrefix . $classDir . DIRECTORY_SEPARATOR . $className . 'php' );
}else{
    throw new Exception( $className . ' could not be found by autoload' );
}