#php #javascript #closures #local-variables
#php #javascript #замыкания #локальные переменные
Вопрос:
У меня есть такая функция:
function get_title($keyword) {
$titles = array(
'p1' => 'Title 1',
'p2' => 'Title 2',
// ... other data
'pm' => 'Some other title',
'pn' => 'One more title'
);
return $titles[$keyword];
}
Хорошая ли практика хранить такой массив в локальной переменной? Например, в нем около 50 названий. Итак, каждый раз, когда я вызываю эту функцию — скрипт загружает 50 заголовков?
Я подумываю об использовании global
, но разве global не плохая практика?
Я новичок в PHP, раньше я писал на JS. В JS я могу сделать это с помощью замыканий:
var get_title = function() {
var titles = {
'p1': 'Title 1',
'p2': 'Title 2',
// ... other data
'pm': 'Some other title',
'pn': 'One more title'
}
return function(keyword) {
return titles[keyword];
}
}();
Здесь title-array не является глобальным, и он не загружается каждый раз, когда я вызываю функцию.
Но как это сделать в PHP?
Комментарии:
1. Звучит как подходящий вопрос для codereview.stackexchange.com
Ответ №1:
Либо:
$titles = array(
'p1' => 'Title 1',
'p2' => 'Title 2',
// ... other data
'pm' => 'Some other title',
'pn' => 'One more title'
);
function get_title($keyword) {
global $titles;
return $titles[$keyword];
}
get_title('p1');
или
class Something {
private static $titles = array(
'p1' => 'Title 1',
'p2' => 'Title 2',
// ... other data
'pm' => 'Some other title',
'pn' => 'One more title'
);
public static function get_title($keyword) {
return self::$titles[$keyword];
}
}
Something::get_title('p1');
Использование статического класса здесь немного похоже на замыкания в Javascript.
Если проблема не связана с памятью, не беспокойтесь об этом.
Ответ №2:
Похоже, что глобальная здесь уместна.
Постарайтесь не обращать внимания на людей, которые говорят, что «такой-то всегда «злой»». Такие обобщения опасны, как вы сейчас обнаруживаете.
Комментарии:
1. Спасибо, вы добавили
()
в мой JS-код. Да, это удобнее, потому что в моем примере после объявления этой функции я должен вызывать ее таким образом:var titles = get_title(); var title1 = titles('p1')
Ответ №3:
$titles
Поступает из базы данных? Если нет, то это действительно микрооптимизация, и я почти могу сказать, что мгновенное изменение этой переменной никогда не будет узким местом, которое стоит оптимизировать.
Однако, если вы действительно хотите, есть два простых решения. Первый из них действительно сохраняет глобальную переменную. Одна из проблем заключается в том, что любой может изменить ваш глобальный массив. Помимо этого, это совсем неплохо.
Другое решение — создать статический класс с $titles
в качестве частного, статического члена. Тогда это просто вопрос создания открытого метода, вызывающего этот массив.
Эти решения создадут экземпляр вашего массива только один раз.
Редактировать: Ах, Frits демонстрирует именно то, что я имею в виду.
Ответ №4:
Я не вижу причин создавать функцию для этого, за исключением того, что вам нужно получить доступ к $title
данным из других функций, и в этом случае вам было бы лучше передать $title
в качестве параметра этим другим функциям.
Ответ №5:
Вы можете очень легко делать то, что хотите, с static
переменной:
function get_title($keyword) {
static $titles = null;
if($titles === null) {
$titles = array(
'p1' => 'Title 1',
'p2' => 'Title 2',
// ... other data
'pm' => 'Some other title',
'pn' => 'One more title'
);
}
return $titles[$keyword];
}
Трюк «инициализировать null
/ проверить / установить значение» (вместо того, чтобы устанавливать значение $titles
напрямую) позволяет вам использовать любой код, который вам нравится, для инициализации переменной (включая непостоянные выражения).
Я бы, конечно, предпочел это вместо a, global
потому что это лучше скрывает детали того, как $titles
создается. Свойство class static — это еще один способ сделать именно это; выбор между ними, ИМХО, зависит от стиля.
Ответ №6:
Ну, в php функциональные переменные являются локальными, они не видны внешнему миру, как в javascript. Если вы хотите, чтобы php var действовал как javascript var, вам нужно будет добавить global перед переменной вот так -> global $var ; Теперь, поскольку вы не хотите устанавливать $ titles при каждом запуске функции, вы можете объявить ее статической вот так
function get_title($keyword) {
static $titles = array(
'p1' => 'Title 1',
'p2' => 'Title 2',
// ... other data
'pm' => 'Some other title',
'pn' => 'One more title'
);
return $titles[$keyword];
}