Pull to refresh

Comments 35

Если честно, ужас какой-то.

Если неизвестно, что с переменными может случиться по дороге, надо код переписывать.
Это используется для разделения логики и представления, в первом скрипте генерируются данные, во втором — HTML-код. При генерации HTML кода хочется использовать PHP-вставки с простыми и понятными именами переменных, например <? echo $order['num'] ?>, а не <? echo $DATA['this_page']['order']['num'] ?>

При этом между первым и вторым скриптом вполне может выполняться другой код, в котором тоже хочется использовать простые и понятные переменные.

Как это можно по другому реализовать?
Необходимость использования такого подхода, когда программист боится, что в данной области видимости могут использоваться другие переменные с такими же именами, свидетельствует о крайне плохом качестве кода.

Посмотрите исходные коды проектов на хорошем современном фреймворке, например, Zend Framework или symfony, и вы поймете, о чем я говорю.

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

Я посмотрел несколько примеров приложений на Symfony, там тоже стремятся использовать короткие понятные переменные для передачи данных в шаблоны. Вы вообще считаете пространства имен дурным тоном, как goto, например?
Проблема такого решения в том, что оно применяется вместо нормального рефакторинга.

Пространства имен — хорошая и полезная вещь, и я не считаю их дурным тоном. Как правильно сказал ниже zerkms, они нужны для объединения классов и функций. Это правильное использование неймспейсов.

Предотвращение конфликтов имен переменных делается максимальным сужением их области видимости, то есть вынесением их из глобальной области видимости в функции и методы классов, и, соответственно, разбиением больших функций и методов на атомарные.
Это все верно, но кроме одного случая — передачи переменных в HTML-представление.

HTML-код должен быть «экстремально» удобочитаемым (иначе можно разориться на верстальщиках), поэтому нужны простые и лаконичные переменные, которых в природе очень мало.

А что Вы подразумеваете под объединением классов и функций?
Это все верно, но кроме одного случая — передачи переменных в HTML-представление.
Используйте класс-шаблонизатор наподобие Zend_View или Smarty или напишите свой аналог. Читаться шаблон будет замечательно.

Объединение классов и функций в неймспейс полезно для предотвращения конфликтов имен классов и функций.

Например ситуация: у вас есть приложение, в котором для некоей задачи вы хотите использовать набор классов стороннего разработчика.
Если в вашем приложении и в стороннем наборе классов если классы с одинаковыми именем, будет проблема с интеграцией.
Если же заранее обернуть все в неймспейсы, проблемы не будет.
Понятно, по сути переменные от классов и не отличаются, глобальный класс или глобальная переменная, какая разница, считайте глобальную переменную классом с одним полем.

Zend_View — это и есть по сути namespace, в этом его основное назначение, единственное, что в коде везде префикс "$this->" мельтишит, было бы хорошо, чтобы и его не было.
что в коде везде префикс "$this->" мельтишит
Это в самом шаблоне? Действительно, не удобно. Смотрите view коханы, там к переменным можно обращаться как есть, префикс $this-> нужен для обращения к переменным и методам текущего контроллера.
То есть вы все-таки считаете, что проект, где большинство переменных являются глобальными — это нормально?

По второму вопросу: если вы боитесь, что верстальщик будет бояться $this->, используйте smarty, и будет у вас

{$order_id}

вместо

<?php echo $this->order_id; ?>

Хотя я бы боялся таких верстальщиков.

А основное назначение шаблонизатора — не хранение переменных шаблона в отдельной области видимости, а разделение логики и представления.
Нет, я считаю само наличие глобальных переменных злом и борюсь с ним по мере своих возможностей.

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

Полное разделение логики и представления — это как коммунизм, очень заманчиво, но пока нереально.
В Zend_View нет отдельного языка для шаблонов, чистый PHP.

По опыту скажу, что к префиксам $this-> в шаблонах привыкаешь за 1-2 часа, и в дальнейшем глаз их просто не замечает. То есть читаемость шаблонов остается на том же уровне.

Согласен, добиться полного разделения логики и представления почти нереально в практических задачах. Но без стремления сделать это обычно выходит плохой неподдерживаемый код.
То есть вы все-таки считаете, что проект, где большинство переменных являются глобальными — это нормально?
Почему вы считаете, что доступность переменных по короткому имени $order_id и их глобальность это одно и тоже? Для примера, когда в шаблоне используется <?= $order_id ?> но при этом переменные локальны, смотреть кохану.
потому что, вероятно, человек не знает, что такое variable scope.
То-то я в ветке комментариев выше пытался убедить человека, что вместо использования псевдонеймспейсов надо разносить переменные по областям видимости :)
Эта фраза относится к
Понятно, по сути переменные от классов и не отличаются, глобальный класс или глобальная переменная, какая разница, считайте глобальную переменную классом с одним полем.
Как это можно по другому реализовать?
Да очень просто.
// Import the view variables to local namespace
extract($view_data, EXTR_SKIP);
Спасибо, не знал про такую функцию, первый раз просто столкнулся с подобной проблемой. Код упрощается.
Нужно было пост назвать: «Как сделать пространства-имён в PHP5.3 ещё большим говном, чем они есть»
А чем Вас пространства имен в PHP 5.3 не устраивают в целом?
постоянной необходимостью указывать контекст и глупым разделителем?
Переменные в глобальной области видимости — суть, глобальные, сами по себе очень редки (в нормальном коде). Фича неймспейсов — в разделении видимости для классов/функций.
Если отрешиться от целесообразности и сконцентрироваться на реализации (графоманство, ага), тогда:
код имеет глупую зависимость от глобальной же переменной $NS, которая может быть легко модифицирована извне. также молчу про eval()
Гораздно элегантее было бы сохранить данные в static массиве в функции, а восстанавливать и сохранять данные, работая с $GLOBALS.
Это всего одна глобальная переменная с «некрасивым» именем (т.е. с небольшой вероятностью повторного использования), вместо нескольких переменных с короткими и часто употребимыми именами.

Вообще я считаю, что для крупных систем, ясность и лаконичность кода — это одно из самых важных требований, поэтому переменные с именами $order, $client, $id, $pay и т.п. очень востребованы, если использовать вместо них какие-то глобальные классы с длинными именами, то читаемость кода сразу сильно ухудшается.

Думаю, что код в идеале должен читаться как простая английская речь.
Думаю, что код в идеале должен читаться как простая английская речь.
Это вы про свой код?
)) Это я про код бизнес-логики системы.
>> Это всего одна глобальная переменная с «некрасивым» именем
а в моём предложении их ноль + хороший способ избавления от евала.
каким боком тут читаемость?
Т.е. Вы предлагаете сделать некий класс и в его static-члене хранить переменные для передачи между скриптами?
нет. static можно объявить и в функции

static $data;
Интересная возможность, тогда в качестве namesapce выступает функция.
Но немного не подходит для передачи данных между скриптами, а $GLOBALS слишком громоздко в коде смотрится.
между скриптами данные передавать нужно через отдельное хранилище и отдельным специально предназначенным для этого кодом. ты задался целью реализовать неймспейсы — вот и реализовывай их, а не греби под себя всё подряд.
$GLOBALS говоришь смотрится громоздко? а ну да, твой евал значительно лучше, нуну.

За сим — не вижу смысла продолжать дискуссию. я всё сказал. считаешь иначе — продолжай плодить говнокод.
Какой ты резкий))

Мой эвал в одной служебной функции, которую никто никогда больше не увидит, а твой $GLOBALS постоянно будет во всех скриптах присутствовать.
не будет. не тупи.

$GLOBALS['var'];

global $var;

это семантически эквивалентные записи.
Я знаю, не хами.

Тогда в начале кода вместо вызова одной функции будет вереница из объявлений global
предлагаю кардинальное решение из разряда «ни тебе ни мне»: отказаться от глобальных переменных. вообще.
Sign up to leave a comment.

Articles