«Пространства имен», константы и несколько PHP включает - PullRequest
2 голосов
/ 19 мая 2009

У меня есть код PHP, похожий на следующий:

foreach ($settingsarray as $settingsfile)
{
    include ($settingsfile);
    // do stuff here
}

$ settingsarray - это массив имен файлов из определенной папки.

Проблема в том, что каждый файл $ settings определяет константы (с одинаковыми именами), которые, конечно, не могут быть переопределены.

Какие существуют возможные способы предотвращения ошибок, возникающих в этой ситуации?

Можно выбрать два варианта: заменить все константы на переменные и использовать пространства имен PHP.

Однако я не уверен, как мне поступить с использованием пространств имен, для этого потребуется объявление в начале каждого файла $ settings? Есть ли способ выделения констант, ариаблей и функций без использования пространств имен?

Что бы мне действительно понравилось, так это возможность делать что-то такое простое, как:

foreach ($settingsarray as $settingsfile)
{
    {//added braces to indicate where the isolation is
        include ($settingsfile);
        // do stuff here
    }//what happens in here does not affect what happens outside of here
}

Должен отметить, что это часть новой функции и единственная часть кода, которая загружает все файлы $ settings. Остальная часть кода загружает только один файл за раз. Одна из причин, по которой я использую константы, заключается в том, что мне не нужно беспокоиться об определении переменных «глобально», чтобы иметь возможность доступа к ним внутри функций.

Ответы [ 5 ]

4 голосов
/ 19 мая 2009

Мой ответ несколько сложен, но должен работать для вас довольно хорошо. Я предполагаю, что у вас есть тонна этих файлов настроек, так как вы не хотите менять каждый из них по отдельности.

Если вы можете использовать пространства имен, я предполагаю, что вы уже обновились до PHP 5.3RC2. Скопируйте следующее в файл .php и измените пространство имен по своему вкусу:

<?php
namespace myapp\config;

function define($key, $val) {
    Config::set($key, $val);
}

class Config {
    private $vars = array();

    // This class should not be instantiated
    private function __construct() {}

    public function set($key, $val) {
        self::$vars[$key] = $val;
    }

    public function get($key) {
        return isset(self::$vars[$key]) ? self::$vars[$key] : NULL;
    }
}

?>

Включите это в свой код, и теперь, чтобы заставить все работать, просто измените

<?php

в ваших файлах настроек до

<?php namespace myapp\config;

Если у вас есть тонна из них, быстрая команда sed в вашем терминале должна позаботиться об этом очень быстро, одним махом.

Если я потерял вас из-за того, как использовать мой код, вот пример:

<?php
require_once('the_php_file_i_just_gave_you.php');
use \myapp\config\Config;

foreach ($settingsarray as $settingsfile) {
    include ($settingsfile);
    $varname = 'key';
    echo "In this file, '$varname' equals: " . Config::get($varname);
}

?>

Удачи!

1 голос
/ 19 мая 2009

непросто, но вы можете прочитать php-файл с помощью file_get_contents ($ settingsfile), затем переписать константы и проверить код.

$settingsstr = file_get_contents($settingsfile);
$settingsstr = preg_replace('/<\?\w*(.*)/', '\\1', $settingsstr);//get rid of the php open tag
$settingsstr = preg_replace('/define\("(\w+)"/', 'define("NAMESPACE_\\1"', $settingsstr);
eval($settingsstr);
1 голос
/ 19 мая 2009

У вас есть несколько вариантов:

Использовать пространства имен PHP

Удивительно, но PHP действительно поддерживает пространства имен . Я был очень удивлен, обнаружив это, так как я работал в PHP в течение многих лет и никогда не слышал об этой функции. Вероятно, это более новая функция, которая обычно не используется, поэтому я бы рекомендовал не использовать этот метод

Использовать константы класса

Вы можете использовать классы и константы классов для загрузки настроек. Константы класса являются локальными для определяющего класса, поэтому вам не нужно беспокоиться о конфликтах имен внутри класса. Возможно, вам потребуется сделать больше, чем просто включить файл, но вы можете вызвать метод для каждого класса, такой как defineConstants () или loadConfiguration (), который определит константы приложения, сохраняя константы класса для внутреннего использования.

Использование функций для расширения настроек

Другая идея заключается в создании массива настроек и отдельных функций для «расширения» этих настроек. Таким образом, вы можете перезаписать любую конфигурацию в последующих функциях, не вызывая ошибки. Наконец, если вы хотите поместить их в константы, вы можете перебрать массив и использовать define () для определения констант.

Есть много других способов выполнить то, что вы пытаетесь сделать, но это всего лишь несколько идей.

1 голос
/ 19 мая 2009

Хорошо, так что, если я правильно вас понимаю, внутри этого цикла вы хотели бы что-то делать с константами, определенными внутри каждого $settingsfile, а затем в основном избавляться от них после каждого цикла?

В отличие от переменных, константа - это значение, которое после установки не может быть изменено или сброшено во время выполнения вашего скрипта ЦСИ

Ваша единственная возможность - изменить объявления define() на переменные.

0 голосов
/ 19 мая 2009

Файл настроек не должен содержать код PHP. Это должен быть какой-то «стандартный» формат. http://www.php.net/parse_ini_file

  • На первом шаге (в вашем foreach) вы читаете все файлы
  • Собрать переменные во временный массив
  • В другом цикле над этим массивом вы можете определить их как константы.

Если вы обычно чувствуете необходимость «переопределить константы», тогда в дизайне приложения что-то не так.

...