在 PHP 中使用已定义的常量

问题描述

这有点长,但我希望能从你们那里得到一些见解。

我正在为 wordpress 编写这个内部工具。今天我们有大约 150 多个站点还活着,这个工具帮助我管理它们。我正在使用文件 wp-config.php获取数据库名称、服务器、用户等。有了这些信息,我就可以从每个站点数据库中获取重要数据。可以使用模板等。与版本号一起,我可以跟踪更新等。它很有用且省时。问题不是 wordpess 特定的所以这就是我把它带到这里的原因。

目前我正在读取 wp-config.php 文件并解析出该信息,这是因为 wp-config.php 文件的编写方式可能会有所不同,其中 ' 周围有额外的空格或没有空格。

问题是在所有站点wp-config.php 中,关键变量都设置为常量。它可能看起来像这样:

define( 'DB_HOST','localhost' );
define( 'DB_USER','mydbuser' );

所以如果我回显 DB_HOST 我得到 localhost 等等。我想知道我是否可以直接使用它们而无需解析它。

但是,这是饼干的症结所在,我有 150 个站点,它们都使用相同的常量,因此在遍历所有站点文件夹并使用“require_once”获取信息并在内存中构建站点列表时我只得到第一个 DB_HOST 和 DB_USER。那是因为它是一个常数,我们无法改变它。我知道这一点,但我还是要试一试。

我尝试设置第二个函数,以便 PHP 会神奇地“忘记”常量,但当然不会。一旦设置了 DB_HOST,它就是。

有什么办法可以使用所有这些 wp-config.php 文件中已经定义的常量,而不用第一个常量阻止下一个同名的常量?

这个问题有点模糊,但我希望你明白我在这里想做什么。

编辑:

这是在遍历所有 wordpress 文件夹的循环中使用的函数的模型。

$in站点所在文件夹的名称/路径。

function templatename($in){
require_once($in.'/wp-config.php'); 

$dbusr = DB_USER;
$dbpass = DB_PASSWORD;
$dbname = DB_NAME;
$dbpref = $databasprefix;
$dbsrv = DB_HOST;

// executing sql connection with the info above retrieving $data 

return $data;

}

因此,为文件kalle 调用 function templatename(kalle); 将返回模板名称 Twentytwenty

解决方法

这不是一个优雅的解决方案,但您可以阅读 wp-config.php 而不是要求它,然后更改常量名称和 eval 代码。

例如,假设您有:

a/wp-config.php

<?php

define( 'DB_HOST','localhost' );
define( 'DB_USER','mydbuser' );
define( 'DB_NAME','abc' );
define( 'DB_PASSWORD','secret' );

b/wp-config.php

<?php

define( 'DB_HOST','localhost2' );
define( 'DB_USER','mydbuser2' );
define( 'DB_NAME','abc2' );
define( 'DB_PASSWORD','secret2' );

您可以使用以下脚本循环遍历所有 wp-config.php 文件:

<?php

function templatename($in,$key) {
    $content = file_get_contents($in.'/wp-config.php');
    $content = str_replace('<?php','',$content);
    $content = str_replace('DB_USER','DB_USER_'.$key,$content);
    $content = str_replace('DB_PASSWORD','DB_PASSWORD_'.$key,$content);
    $content = str_replace('DB_NAME','DB_NAME_'.$key,$content);
    $content = str_replace('DB_HOST','DB_HOST_'.$key,$content);

    eval($content);

    $dbusr = constant('DB_USER_'.$key);
    $dbpass = constant('DB_PASSWORD_'.$key);
    $dbname = constant('DB_NAME_'.$key);
    $dbpref = $databasprefix;
    $dbsrv = constant('DB_HOST_'.$key);

    echo "User ".$dbusr." / Pass ".$dbpass." / Name ".$dbname." / Host ".$dbsrv."\n";

    // executing SQL connection with the info above retrieving $data 

    // return $data;
}

foreach(['a','b'] as $key => $dir) {
    templatename($dir,$key);
}

它返回:

User mydbuser / Pass secret / Name abc / Host localhost
User mydbuser2 / Pass secret2 / Name abc2 / Host localhost2

在任何语言中使用 eval 都是危险的,如果你不知道你正在评估什么,但它并不比要求更危险;当然,这是一种“肮脏”的解决方案,不推荐用于生产环境。