Вялый userinfo php. Принимая PHP всерьёз

Фильтры в Revolution позволяют манипулировать тем, как будут обрабатываться те или иные теги. Они позволяют вам изменять значения прямо внутри ваших шаблонов.

Фильтры ввода

В настоящее время фильтры ввода используются при подготовке к обработке фильтров вывода. Обычно они используются только внутри движка MODX.

Фильтры вывода

В Revolution фильтры вывода ведут себя так же, как и PHx в Evolution, только фильтры теперь встроены прямо в движок MODX. Синтаксис выглядит так:

[]

Фильтры могут применяться последовательно. Для этого напишите их подряд (слева направо):

[]

Также фильтры могут применяться для модификации вывода сниппетов. Фильтр нужно прописывать перед всеми параметрами (перед знаком вопроса):

[]

Модификаторы вывода

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

Условные модификаторы вывода

Модификатор Описание Пример использования
if, input Передаёт произвольный текст на ввод, для следующего модификатора [[*id:input=`[[+placeholder]]`:is=`1`:then=`Да`:else=`Нет`]]
or ИЛИ [[+numbooks:is=`5`:or:is=`6`:then=`Здесь 5 или 6 книг`:else=`Не уверен, сколько книг`]]
and Объединение нескольких модификаторов связью И [[+numbooks:gt=`5`:and:lt=`10`:then=`Здесь от 5 до 10 книг`:else=`Книг или меньше 5, или больше 10`]]
isequalto, isequal, equalto, equals, is, eq Сравнивает передаваемое значение с установленным. Если значения совпадают, выводится значение «then», если нет - «else» [[+numbooks:isequalto=`5`:then=`Здесь 5 книг`:else=`Не уверен, сколько книг`]]
notequalto, notequals, isnt, isnot, neq, ne Сравнивает передаваемое значение с установленным. Если значения НЕ совпадают, выводится значение «then», если нет - «else» [[+numbooks:notequalto=`5`:then=`Не уверен, сколько книг`:else=`Здесь 5 книг`]]
greaterthanorequalto, equalorgreaterthen, ge, eg, isgte, gte То же, только условие «Больше или равно» [[+numbooks:gte=`5`:then=`Здесь 5 книг или больше`:else=`Здесь меньше пяти книг`]]
isgreaterthan, greaterthan, isgt, gt То же, только условие «Строго больше» [[+numbooks:gt=`5`:then=`Здесь больше пяти книг`:else=`Здесь 5 книг или меньше`]]
equaltoorlessthan, lessthanorequalto, el, le, islte, lte То же, только условие «Меньше или равно» [[+numbooks:lte=`5`:then=`Здесь 5 книг или меньше`:else=`Здесь больше пяти книг`]]
islowerthan, islessthan, lowerthan, lessthan, islt, lt То же, только условие «Строго меньше» [[+numbooks:lte=`5`:then=`Здесь меньше пяти книг`:else=`Здесь 5 книг или больше`]]
hide Скрывает элемент, если условие выполняется [[+numbooks:lt=`1`:hide]]
show Отображает элемент, если условие выполняется [[+numbooks:gt=`0`:show]]
then Используется для составления условий [[+numbooks:gt=`0`:then=`Книги в наличии!`]]
else Используется для составления условий (совместно с «then») [[+numbooks:gt=`0`:then=`Книги в наличии!`:else=`Простите, но все продано.`]]
memberof, ismember, mo Проверяет, является ли пользователь членом указанной группы пользователей [[!+modx.user.id:memberof=`Administrator`]]

Модификаторы для работы со строками

Модификатор Описание Пример использования
cat Добавляет значение после тега [[+numbooks:cat=`книг`]]
lcase, lowercase, strtolower Переводит все буквы в нижний регистр [[+title:lcase]]
ucase, uppercase, strtoupper Переводит все буквы в верхний регистр [[+headline:ucase]]
ucwords Делает первую букву в словах заглавной [[+title:ucwords]]
ucfirst Делает первую букву в строке заглавной [[+name:ucfirst]]
htmlent, htmlentities Преобразует все символы в соответствющие HTML-сущности [[+email:htmlent]]
esc, escape Безопасно экранирует символы, используя регулярные выражения и `str_replace()`. Также экранирует теги MODX. [[+email:escape]]
strip Заменяет все переносы, табуляции и любое количество пробелов только одним пробелом [[+textdocument:strip]]
stripString Вырезает из строки указанную подстроку [[+name:stripString=`Mr.`]]
replace Производит замену подстрок [[+pagetitle:replace=`Mr.==Mrs.`]]
striptags, stripTags,notags,strip_tags Вырезает все теги (можно указать разрешенные теги). Не используйте для обеспечения безопасности. [[+code:strip_tags]]
len,length, strlen Выводит длину строки [[+longstring:strlen]]
reverse, strrev Переворачивает строку символ за символом [[+mirrortext:reverse]]
wordwrap Вставляет перенос строки после каждого n-ого символа (слова не разбиваются) [[+bodytext:wordwrap=`80`]]
wordwrapcut Вставляет перенос строки после каждого n-ого символа, даже если этот символ будет внутри слова [[+bodytext:wordwrapcut=`80`]]
limit Выводит определенное количество символов с начала строки (значение по умолчанию - 100) [[+description:limit=`50`]]
ellipsis Добавляет многоточие и обрезает строку, если она длиннее, чем указанное количество символов (по умолчанию - 100) [[+description:ellipsis=`50`]]
tag Экранирование. Отображает элемент так как он есть, без:tag. Для использования в документации [[+showThis:tag]]
add, increment, incr Прибавляет указанное число (значение по умолчанию +1) [[+downloads:incr]] [[+blackjack:add=`21`]]
subtract, decrement, decr Вычитает указанное число (значение по умолчанию -1) [[+countdown:decr]] [[+moneys:subtract=`100`]]
multiply, mpy Умножает на указанное число (значение по умолчанию *2) [[+trifecta:mpy=`3`]]
divide,div Делит на указанное число (значение по умолчанию /2) [[+rating:div=`4`]]
modulus,mod Возвращает модуль числа (по умолчанию: %2, возвращает 0 или 1) [[+number:mod]]
ifempty,default,empty, isempty Возращает значение модификатора, если значение тега пусто [[+name:default=`anonymous`]]
notempty, !empty, ifnotempty, isnotempty Возращает значение модификатора, если значение тега не пусто [[+name:notempty=`Hello [[+name]]!`]]
nl2br Заменяет символы новой строки \n на HTML-тег br [[+textfile:nl2br]]
date Переводит таймстамп в текст, в соответствии с указанным форматом (формат даты) [[+birthyear:date=`%Y`]]
strtotime Переводит дату в виде текста в UNIX таймстамп [[+thetime:strtotime]]
fuzzydate Принимает таймстамп и возвращает дату в виде "Сегодня в 16:20 PM" [[+createdon:fuzzydate]]
ago Возвращает число секунд, минут, недель или месяцев, прошедших с даты, указанной в теге. [[+createdon:ago]]
md5 Создает MD5-хеш значения [[+password:md5]]
cdata Оборачивает вывод тегами CDATA [[+content:cdata]]
userinfo Возвращает запрашиваемое значение из профиля пользователя. Необходимо указывать ID пользователя [[!+modx.user.id:userinfo=`username`]]
isloggedin Возвращает 1, если пользователь авторизован в текущем контексте [[!+modx.user.id:isloggedin:is=`1`:then=`Yes`:else=`No`]]
isnotloggedin Возвращает 1, если пользователь не авторизован в текущем контексте [[!+modx.user.id:isnotloggedin:is=`1`:then=`No`:else=`Yes`]]
urlencode Конвертирует значение как URL, то есть применяет PHP фнукцию `urlencode()` [[+mystring:urlencode]]
urldecode Конвертирует значение как из URL, то есть применяет PHP фнукцию `urldecode()` [[+myparam:urldecode]]

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

Использование модификаторов вывода совместно с параметрами

Если у тега есть параметры, то их необходимо прописывать сразу после модификатора:

[[!getResources:default=`К сожалению, ничего не найдено`? &tplFirst=`blogTpl` &parents=`2,3,4,8` &tvFilters=`blog_tags==%[[!tag:htmlent]]%` &includeTVs=`1` ]]

Создание пользовательского модификатора

Любой сниппет может использоваться как модификатор вывода. Для этого просто укажите имя сниппета вместо модификатора. К примеру, создадим сниппет [] , добавляющий к выводу определенное количество восклицательных знаков:

[[*pagetitle:makeExciting=`4`]]

Такой вызов тега передаст в сниппет makeExciting следующие параметры для обработки:

Параметр Значение Значение в примере

Ракета Союз, доставленная на поезде на пусковую площадку. Фото из общественного достояния NASA.

Добродетели PHP

PHP имеет несколько очень глубоких и, однозначно, верных особенностей.

Первая, состояние . Каждый веб-запрос начинается с совершенно чистого листа. Его пространство имён и глобальные переменные не инициализированы, за исключением некоторых стандартных глобальных переменных, функций и классов, которые предоставляют примитивную функциональность и жизнеобеспечение. Начиная каждый запрос с известного состояния, мы получаем своего рода изоляцию от возможных ошибок; если запрос t сталкивается с неполадкой ПО и завершается с ошибкой, данный баг не оказывает никакого влияния на выполнение последующего запроса t+1. В действительности, конечно же, помимо программной кучи, состояние приложения находится и в других местах, и вполне возможно полностью испортить базу данных, memcache или файловую систему. Но PHP разделяет эту слабость со всеми мыслимыми средами, которые позволяют сохранять состояние. В то же время, разделение программных куч между запросами снижает цену большинства программных ошибок.

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

В заключении, тот факт, что PHP программы оперируют на уровне запросов, означает, что рабочий процесс программиста является быстрым и эффективным, и остаётся быстрым после изменения приложения. Множество языков продуктивной разработки претендуют на это, но если они не очищают своё состояние при каждом запросе, и основной поток событий разделяет программный уровень состояния между запросами, они почти всегда требуют некоторое время на запуск. Для типичного сервера приложений на Python"е, типичный цикл отладки будет выглядеть примерно как «подумать, отредактировать, перезапустить сервер, отправить несколько тестовых запросов». Даже если «перезапустить сервер» занимает всего несколько секунд из общего количества часов, это забирает большой срез из 15-30 секунд наших человеческих мозгов на необходимость удержания в голове самой ненужной части текущего состояния.

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

Доводы против PHP

Если всё это является правдой, почему же его так ненавидят ? Когда вы уберёте все красочные гиперболы в сторону, что основные жалобы о PHP кластере сведутся к следующим проблемам:


Чтобы не показаться нерефлективным апологетом PHP: всё это серьёзные проблемы, которые позволяют более вероятно создавать дефекты. Они являются явными ошибками (unforced errors). Здесь нет присущего компромисса между Хорошими Частями PHP и данными проблемами. Должна быть реализована возможность создать PHP, который разрешит данные недостатки, сохранив при этом все хорошие стороны.

HHVM и Hack

Этот преемник системы PHP зовётся Hack

Hack - это такой язык программирования, который люди называют «постепенная система типов» для PHP. «Система типов» значит, что он позволяет программисту составлять автоматически проверяемые инварианты о данных, которые протекают через код: данная функция берёт строку или число и возвращает лист Fribbles, как например в Java или C++ или Haskell, или в любом другом статически типизированном языке, который вы выберете. «Постепенная» означает, что некоторые части вашей кодовой базы могут быть статически типизированными, в то время как другие её части могут всё ещё находится в беспорядочном, динамическом PHP. Возможность совмещать эти подходы позволяет постепенно мигрировать большие кодовые базы.

Вместо того чтобы разлить здесь тонны чернил в описании системы типов Hack и того, как она работает, просто поиграйтесь с ним . Я буду здесь, когда вы вернётесь.

Это аккуратная система, и она весьма амбициозна в том что она позволяет вам выразить. И наличие возможности постепенной миграции проекта на Hack, в случаях когда он разрастается сильнее, чем вы ожидали изначально, является уникальным преимуществом экосистемы PHP. Проверки типов Hack сохраняют рабочий процесс в стиле «думать, отредактировать, перезагрузить страницу», потому что они запускаются в фоне, постепенно обновляя модель кодовой базы, когда он видит модификации в файловой системе. Проект Hack предоставляет интеграции со всеми популярными редакторами и IDE, так что вы сможете увидеть обратную связь об ошибках типов уже тогда, когда завершите печатать код, также как в веб-демонстрации.

Давайте рассмотрим совокупность реальных рисков, которые создаёт PHP, в свете Hack:


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

HHVM

Hack изначально был разработан как часть виртуальной машины HipHop , или HHVM, виртуальной среды с открытым исходным кодом для PHP. HHVM предоставляет другую важную опцию для успешного проекта: возможность запустить ваш сайт быстрее и более экономно. Facebook
  1. Перегрузка свойств классов
  2. Обращения к свойствам объекта могут быть перегружены с использованием методов __call , __get и __set . Эти методы будут срабатывать только в том случае, если объект или наследуемый объект не содержат свойства, к которому осуществляется доступ. Синтаксис такой:

    void __set (string имя, mixed значение)

    Void __get (mixed имя)

    С помощью этих методов обращения к свойствам класса могут быть перегружены с целью выполнения произвольного кода, описанного в классе. В аргументе имя передаётся имя свойства, к которому производится обращение. Аргумент значение метода __set() должен содержать значение, которое будет присвоено свойству класса с именем имя.

    __get и __set :

    class Setter {
    public $n ;
    private $x = array("a" => 1 , "b" => 2 , "c" => 3 );

    Function __get ($nm ) {
    print "Читаем [$nm]\n" ;

    If (isset($this -> x [ $nm ])) {
    $r = $this -> x [ $nm ];
    print "Получили: $r\n" ;
    return $r ;
    } else {
    print "Ничего!\n" ;
    }
    }

    Function __set ($nm , $val ) {
    print "Пишем $val в [$nm]\n" ;

    If (isset($this -> x [ $nm ])) {
    $this -> x [ $nm ] = $val ;
    print "OK!\n" ;
    } else {
    print "Всё плохо!\n" ;
    }
    }
    }

    $foo = new Setter ();
    $foo -> n = 1 ;
    $foo -> a = 100 ;
    $foo -> a ++;
    $foo -> z ++;
    var_dump ($foo );
    ?>

    Результатом выполнения рассмотренного скрипта будет:

    Пишем 100 в [a]
    OK!
    Читаем [a]
    Получили: 100
    Пишем 101 в [a]
    OK!
    Читаем [z]
    Ничего!
    Пишем 1 в [z]
    Всё плохо!
    object(Setter)#1 (2) {
    ["n"]=>
    int(1)
    ["x:private"]=>
    array(3) {
    ["a"]=>
    int(101)
    ["b"]=>
    int(2)
    ["c"]=>
    int(3)
    }
    }

  3. Перегрузка методов
  4. Вызовы методов могут быть перегружены с использованием методов __call , __get и __set . Эти методы будут срабатывать только в том случае, если объект или наследуемый объект не содержат метода, к которому осуществляется доступ. Синтаксис:

    mixed __call (string имя, array аргументы)

    С использованием этого метода, методы класса могут быть перегружены с целью выполнения произвольного кода, описанного в классе. В аргументе имя передаётся имя вызванного метода. Аргументы, которые были переданы методу при обращении, будут возвращены чере аргументы. Значение, возвращённое методом __call() , будет передано вызывающему оператору.

    Пример перегрузки с использованием __call :

    class Caller {
    private $x = array(1 , 2 , 3 );

    Function __call ($m , $a ) {
    print "Вызван метод $m:\n" ;
    var_dump ($a );
    return $this -> x ;
    }
    }

    $foo = new Caller ();
    $a = $foo -> test (1 , "2" , 3.4 , true );
    var_dump ($a );
    ?>

    Результат выполнения рассмотренного примера:

    Вызван метод test:
    array(4) {
    =>
    int(1)
    =>
    string(1) "2"
    =>
    float(3.4)
    =>
    bool(true)
    }
    array(3) {
    =>
    int(1)
    =>
    int(2)
    =>
    int(3)
    }

  5. Интерфейсы

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

    Интерфейсы объявляются так же, как и обычные классы, но с использованием ключевого слова "interface "; тела методов интерфейсов должны быть пустыми. Для включения интерфейса в класс программист должен использовать ключевое слово "implements " и описать функционал методов, перечисленных во включаемом интерфейсе. Если это требуется, классы могут включать более одного интерфейса путём их перечисления через пробел.

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

    interface ITemplate
    {
    public function setVariable ($name , $var );
    public function getHtml ($template );
    }

    Class Template implements ITemplate
    {
    private $vars = array();

    Public function setVariable ($name , $var )
    {
    $this -> vars [ $name ] = $var ;
    }

    Public function getHtml ($template )
    {
    foreach($this -> vars as $name => $value ) {
    $template = str_replace ("{" . $name . "}" , $value , $template );
    }

    Return $template ;
    }
    }
    ?>

  6. Оператор instanceof

    Поддержка проверки зависимости от других объектов. Функцией is_a(), известной из PHP 4, пользоваться теперь не рекомендуется.

    if ($obj instance of Circle ) {
    print "$obj is a Circle" ;
    }
    ?>

  7. Метод final

    Ключевое слово final позволяет вам помечать методы, чтобы наследующий класс не мог перегрузить их. Разместив перед объявлениями методов или свойств класса ключевое слово final , вы можете предотвратить их переопределение в дочерних классах, например:

    class BaseClass {
    public function test () {
    echo "Вызван метод BaseClass::test()\n" ;
    }

    Final public function moreTesting () {
    echo "Вызван метод BaseClass::moreTesting()\n" ;
    }
    }

    Class ChildClass extends BaseClass {
    public function moreTesting () {
    echo "Вызван метод ChildClass::moreTesting()\n" <<< Назад

    Содержание Вперед >>>
    Есть еще вопросы или что-то непонятно - добро пожаловать на наш