从PHP编写PHP的正确方法

时间:2014-08-01 21:27:58

标签: php

我正在编写一个安装脚本,用户将通过<form>输入他们的数据库信息。

我想要获取这些值,最终以

结束
<?php
define("WEBSITE_TITLE", "");
define("DATABASE_HOST", "hostnameValue");
define("DATABASE_USER", "usernameValue");
define("DATABASE_PASS", "passwordValue");
define("DATABASE_NAME", "dbNameValue");
?>

config.php已经存在,开箱即用的所有内容都是:

<?php
define("WEBSITE_TITLE", "Data Share | File Manager");

我现在正在使用它,但它有点像黑客

$file = '../config.php';

$current = file_get_contents($file);
$current .= "\ndefine(\"DATABASE_HOST\", \"" . $request->hostname . "\");\n";
$current .= "define(\"DATABASE_USER\", \"" . $request->username . "\");\n";
$current .= "define(\"DATABASE_PASS\", \"" . $request->password . "\");\n";
$current .= "define(\"DATABASE_NAME\", \"" . $request->dbname . "\");\n";
$current .= "?>";

$save = file_put_contents($file, $current);

以上的IS工作正常,但我想知道他们是否是更好或更正确的方法。

3 个答案:

答案 0 :(得分:1)

这是我为处理类似任务而编写的函数的改编版本。

您的解决方案的主要区别在于,它使用文件锁定来防止数据损坏或配置文件的并发命中可能出现的不一致。此解决方案也足够灵活,可应用于不同的配置文件类型/格式,足够强大,可扩展到处理(几乎)任意数量的配置选项,还可处理文件中预先存在的配置选项。

尽管如此,我认为这不会为您的有限用例解决方案提供任何真正的好处。

<?php
function writeConfig($filePath, array $configs, $clear=false)
{
    // scanf/sprintf format string to parse/print configs
    $configParseFormat = "define('%[^']s', '%[^']s');";
    $configWriteFormat = "define('%s', '%s');\n";

    // Open file for reading/writing
    if ($fp = fopen($filePath, 'c+')) {
        // Get file lock
        if (flock($fp, LOCK_EX)) {

            // Check if current configs should be kept
            if (!$clear) {
                // Read in configs from file and add to new configs array
                while (list($key, $value) = fscanf($fp, $configParseFormat)) {
                    if (!empty(trim($key)) && !array_key_exists($key, $configs)) {
                        $configs[ $key ] = $value;
                    }
                }
            }

            // Clear out file contents
            ftruncate($fp, 0);
            rewind($fp);

            // Start php file
            fwrite($fp, "<?php\n");

            // Loop through all config values
            foreach ($configs as $key => $value) {
                // Write the config line
                fprintf($fp, $configWriteFormat, $key, $value);
            }

            // Flush output and release lock
            fflush($fp);
            flock($fp, LOCK_UN);

            return fclose($fp);
        }

        // Close file
        fclose($fp);
    }

    return false;
}

// E.g use:
writeConfig('config.php', array(
    'DATABASE_HOST' => $request->hostname,
    'DATABASE_PASS' => $request->password,
    'DATABASE_USER' => $request->username,
    'DATABASE_NAME' => $request->dbname
    // WEBSITE_TITLE and any configs already in file will be retained
));

答案 1 :(得分:0)

实际上没有太多其他方法(除了使用数组)可能更好。使用数组可能不那么“hacky”,但better实际上是被解释的。

$file = '../config.php';
$current = file_get_contents($file);

$define = array("DATABASE_HOST" => "\$request->hostname",
                "DATABASE_USER" => "\$request->username",
                "DATABASE_PASS" => "\$request->password",
                "DATABASE_NAME" => "\$request->dbname");

foreach($define as $key => $value) {
    $current .= "\ndefine(\"".$key."\", \"".$value."\");";
}
$current .= "\n?>";

$save = file_put_contents($file, $current);

答案 2 :(得分:0)

您可以使用json_encode() file_put_contents()

以JSON格式存储配置
$config = array('database' => array('host' => 'example'));
file_put_contents('config.json', json_encode($config));

然后你可以创建一个加载这个文件的Config类:

class Config
{
    private $config;

    private function load() {
        $string = file_get_contents('config.json');
        $this->config = json_decode($string);
    }

    public function __get($name) {
        // Lazy load configuration file
        if(!isset($this->config)) {
            $this->load();
        }

        return $this->config->$name;
    }
}

用法很简单,只需创建类的实例并访问对象变量:

$config = new Config();
echo $config->database->host; // Outputs 'example'

稍后您可以使Config类成为更高效的单例,如果无法加载文件则添加错误处理等。