Fat-Free Фреймворк — полное описание

fat-treeСегодня представляем вашему вниманию мощный, но простой в использовании микро-фреймворк PHP, разработанный, для того чтобы помочь вам быстро создавать динамичные и надежные веб-приложения!

Сжатый в одном файле размером ~ 65 КБ, F3 (как мы его с любовью называем) дает вам прочную основу, развитую базу кода и безошибочный подход к написанию веб-приложений. Под капотом находится простой в использовании набор инструментов для веб-разработки, высокопроизводительный механизм маршрутизации и кэширования URL-адресов, встроенная подсветка кода и поддержка многоязычных приложений. Это легкий, простой в использовании и быстрый. Больше всего, это не мешает вам.

Будь вы новичок или опытный программист PHP, F3 поможет вам в кратчайшие сроки. Нет ненужных и кропотливых процедур установки. Не требует сложной конфигурации. Нет запутанных структур каталогов. Нет лучшего времени, чтобы начать разработку веб-приложений проще, чем сейчас!

F3 поддерживает готовые базы данных SQL и NoSQL: MySQL, SQLite, MSSQL / Sybase, PostgreSQL, DB2 и MongoDB. Он также поставляется с мощными объектно-реляционными сопоставителями для абстракции и моделирования данных, которые так же легки, как и фреймворк. Конфигурация не требуется.

Это не все. F3 поставляется с другими дополнительными плагинами, которые расширяют его возможности:

Быстрый и чистый шаблонный движок,
Инструментарий модульного тестирования,
Сеансы под управлением базы данных с автоматической защитой CSRF,
Конвертер Markdown-to-HTML,
Atom / RSS-ридер,
Процессор изображений,
Обработчик геоданных,
Google статические карты,
Компрессор Javascript / CSS на лету,
OpenID (потребитель),
Пользовательский регистратор,
Корзина / Корзина,
Pingback сервер / потребитель,
Строковые функции с поддержкой Юникода,
SMTP через SSL / TLS,
Инструменты для общения с другими серверами,
И конечно же в крошечной упаковке с наддувом!

В отличие от других платформ, F3 стремится быть пригодным для использования — не обычно.

Flattr этот проект

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

Оглавление:

Начнем от печки
Как выполняется маршрутизация
Рамочные переменные
Представления и шаблоны
Базы данных, подключение и использование
Плагины и их использование
Оптимизация или чтобы еще подкрутить?
Модульное тестирование
Краткий справочник движка
Поддержка и лицензирование

Версия 3.6 наконец выпущена!

Последний официальный релиз встречает новый год с новой силой и знаменует собой последний рубеж в этой версии Fat-Free Framework. Версия 3.6 с потрясающими новыми функциями и выдающейся документацией, которая потребовала значительного времени и усилий для разработки и совершенствования, теперь доступна для загрузки. Это издание содержит множество новых функций удобства и безопасности.

F3 имеет стабильную архитектуру корпоративного класса. Непревзойденная производительность, удобные функции и легкая площадь. О чем вы еще хотите попросить?

Настоятельно рекомендуется, чтобы опытные пользователи разрабатывали новые приложения с этой версией, чтобы воспользоваться преимуществами новейшей кодовой базы и ее значительными улучшениями.
Представляем FatFreeFramework.com

Подробную документацию по API с большим количеством примеров кода и графическое руководство теперь можно найти по адресу http://fatfreeframework.com/ .

Конечно, этот удобный онлайн-справочник работает на F3! Он демонстрирует возможности и производительность фреймворка. Проверьте это сейчас.
Начиная

Дизайнер знает, что достиг совершенства не тогда, когда нечего добавить, а когда нечего убрать. — Антуан де Сент-Экзюпери

Fat-Free Framework позволяет легко создавать целые веб-сайты в один миг. Обладая той же мощью и краткостью, что и современные наборы инструментов и библиотек Javascript, F3 помогает вам писать более привлекательные и надежные программы на PHP. Один взгляд на ваш исходный код PHP, и любой поймет, как легко понять, как много вы можете сделать за несколько строк кода и насколько эффективны результаты.

F3 — одна из лучших документированных сред. Обучение это стоит почти ничего. Нет строгого набора сложных для навигации структур каталогов и навязчивых шагов программирования. Не нужно загружать параметры конфигурации, чтобы отобразить ‘Hello, World’ в вашем браузере. Fat-Free дает вам большую свободу — и стиль — чтобы выполнять больше работы с легкостью и за меньшее время.

Декларативный подход F3 к программированию облегчает как новичкам, так и экспертам понимание кода PHP. Если вы знакомы с языком программирования Ruby, вы заметите сходство между Fat-Free и микро-фреймворком Sinatra, поскольку они оба используют простой предметно-ориентированный язык для веб-сервисов ReSTful. Но в отличие от Sinatra и его PHP-воплощений (Fitzgerald, Limonade, Glue и многие другие), Fat-Free выходит за рамки простой обработки маршрутов и запросов.

Представления могут быть в любой форме, такой как простой текст, HTML, XML или сообщение электронной почты. Фреймворк поставляется с быстрым и простым в использовании механизмом шаблонов. F3 также без проблем работает с другими шаблонизаторами, включая Twig, Smarty и сам PHP. Модели взаимодействуют с сопоставителями данных F3 и помощником SQL для более сложных взаимодействий с различными механизмами баз данных. Другие плагины расширяют базовую функциональность еще больше. Это общая платформа веб-разработки — с большим запасом!

Хватит говорить — смотрите сами

Распакуйте содержимое дистрибутива в любое место на вашем жестком диске. По умолчанию файл фреймворка и дополнительные плагины находятся в lib/ path. Организуйте свои структуры каталогов так, как вы хотите. Вы можете переместить папки по умолчанию в путь, который не доступен через Интернет для большей безопасности. Удалите плагины, которые вам не нужны. Вы всегда можете восстановить их позже, и F3 обнаружит их присутствие автоматически.

Важное замечание : Если ваше приложение использует APC, Memcached, WinCache, XCache или кеш файловой системы, сначала очистите все записи в кеше, прежде чем перезаписывать старую версию фреймворка новой.

Убедитесь, что вы используете правильную версию PHP. F3 не поддерживает версии более ранние, чем PHP 5.4. Вы будете получать синтаксические ошибки (ложные срабатывания) повсюду, потому что новые языковые конструкции и замыкания / анонимные функции не поддерживаются устаревшими версиями PHP. Чтобы узнать это, откройте консоль (оболочка bash в GNU / Linux или cmd.exe в Windows): —

/path/to/php -v

PHP даст вам знать, какую именно версию вы используете, и вы должны получить что-то похожее на это: —

PHP 5.4.30 (cli) (built: Jul 22 2014 21:34:41) Copyright (c) 1997-2014 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans 

Обновите при необходимости и вернитесь сюда, если вы перешли на PHP 5.4 или более позднюю версию. Если вам нужен хостинг-провайдер PHP 5.4+, попробуйте один из следующих сервисов:

    А2 Хостинг
    DreamHost
    Hostek
    SiteGround 

Hello, World: менее чем за минуту без плясок с бубном

Время начать писать наше первое приложение: —

$f3 = require('path/to/base.php');
$f3->route('GET /',
    function() {
        echo 'Hello, world!';
    }
);
$f3->run();

base.php первой строке base.php с соответствующим путем. Сохраните приведенный выше фрагмент кода как index.php в корневой веб-папке. Мы написали нашу первую веб-страницу.

Используете composer? Тогда просто запустите composer require bcosca/fatfree и используйте следующее:

require 'vendor/autoload.php';
$f3 = \Base::instance();
$f3->route('GET /',
    function() {
        echo 'Hello, world!';
    }
);
$f3->run(); 

Первая команда сообщает интерпретатору PHP, что вы хотите, чтобы функции и возможности платформы были доступны для вашего приложения. Метод $f3->route() сообщает Fat-Free, что веб-страница доступна по относительному URL, указанному косой чертой ( / ). Любой, кто посетит ваш сайт, расположенный по адресу http://www.example.com/ , увидит ‘Hello, world!’ сообщение, потому что URL / эквивалентен корневой странице. Чтобы создать маршрут, который разветвляется от корневой страницы, например http://www.example.com/inside/ , вы можете определить другой маршрут с помощью простой строки GET /inside .

Описанный выше маршрут указывает платформе на визуализацию страницы только при получении запроса URL-адреса с использованием метода HTTP GET . Более сложные веб-сайты, содержащие формы, используют другие методы HTTP, такие как POST , и вы также можете реализовать это как часть $f3->route().

Если платформа видит входящий запрос для вашей веб-страницы, расположенный по корневому URL / , она автоматически направляет запрос в функцию обратного вызова, которая содержит код, необходимый для обработки запроса и рендеринга соответствующего HTML-содержимого. В этом примере мы просто отправляем строку ‘Hello, world!’ в веб-браузер пользователя.

Итак, мы создали наш первый маршрут. Но это ничего не даст, кроме как сообщить F3, что есть процесс, который будет его обрабатывать, и есть текст для отображения в веб-браузере пользователя. Если у вас намного больше страниц на вашем сайте, вам нужно настроить разные маршруты для каждой группы. А пока давайте будем простыми. Чтобы $f3->run() платформе начать ожидание запросов, мы $f3->run() команду $f3->run() .

Не получается запустить пример? Если у вас возникли проблемы с запуском этой простой программы на вашем сервере, вам, возможно, придется немного изменить настройки веб-сервера. Взгляните на пример конфигурации Apache в следующем разделе (вместе с эквивалентами Nginx и Lighttpd).

Все еще есть проблемы? Убедитесь, что $f3 = require(‘path/to/base.php’); назначение происходит перед любым выводом в вашем скрипте. base.php изменяет заголовки HTTP, поэтому любой символ, который выводится в браузер до этого назначения, вызовет ошибки.

Маршрутный двигатель

Обзор.

Наш первый пример не был слишком трудным для глотания, не так ли? Если вам нравится немного больше вкуса в вашем супе без жира, вставьте другой маршрут перед командой

$f3->run() : -

$f3->route('GET /about',
    function() {
        echo 'Donations go to a local charity... us!';
    }
); 

Вы не хотите загромождать глобальное пространство имен именами функций? Fat-Free распознает различные способы отображения обработчиков маршрутов в классы и методы ООП:

class WebPage {
    function display() {
        echo 'I cannot object to an object';
    }
}

$f3->route('GET /about','WebPage->display'); 

HTTP-запросы также могут быть направлены на методы статического класса:

$f3->route(‘GET /login’,’Auth::login’);

Переданные аргументы всегда указываются в качестве второго параметра:

$f3->route('GET /hello/@name','User::greet');

class User {
	public static function greet($f3, $args) { //$args is type of Array
		echo "Hello " . $args['name'];
	}
}

Если заданный аргумент name будет foo (/ hello / foo), будет показан следующий вывод:

Hello foo

Маршруты и токены

В качестве демонстрации мощного предметно-ориентированного языка (DSL) Fat-Free вы можете указать один маршрут для обработки различных возможностей: —

$f3->route('GET /brew/@count',
    function($f3) {
        echo $f3->get('PARAMS.count').' bottles of beer on the wall.';
    }
);

В этом примере показано, как мы можем указать токен @count для представления части URL. Фреймворк будет обслуживать любой URL-адрес запроса, который соответствует префиксу /brew/ , например /brew/99 , /brew/98 и т. Д. Это будет отображать « ’99 bottles of beer on the wall’ и « ’98 bottles of beer on the wall’ соответственно. Fat-Free также примет запрос страницы для /brew/unbreakable. (Ожидайте, что это покажет ‘unbreakable bottles of beer on the wall’ .)

Когда такой динамический маршрут указан, Fat-Free автоматически заполняет глобальную переменную массива PARAMS значением захваченных строк в URL. $f3->get() внутри функции обратного вызова извлекает значение переменной структуры. Конечно, вы можете применить этот метод в своем коде как часть презентации или бизнес-логики. Но мы обсудим это более подробно позже.

Обратите внимание, что Fat-Free понимает точечные обозначения массива. Вместо этого вы можете использовать обычную запись PARAMS[‘count’] вместо кода в коде, который подвержен ошибкам опечаток и несбалансированным скобкам. В представлениях и шаблонах платформа допускает нотацию @PARAMS.count которая в некоторой степени похожа на Javascript. (Мы рассмотрим виды и шаблоны позже.)

Вот еще один способ получить доступ к токенам в шаблоне запроса:

$f3->route('GET /brew/@count',
    function($f3,$params) {
        echo $params['count'].' bottles of beer on the wall.';
    }
);

Вы можете использовать звездочку ( * ), чтобы принять любой URL-адрес после маршрута /brew — если вы действительно не заботитесь об остальной части пути: —

$f3->route('GET /brew/*',
    function() {
        echo 'Enough beer! We always end up here.';
    }
);

Важный момент, на который следует обратить внимание: вы будете сбиты с толку обезжиренным (и самим), если в одном приложении у вас есть и GET /brew/@count и GET /brew/* . Используйте один или другой. Другое дело: Fat-Free рассматривает GET /brew как отдельный и отличный от маршрута GET /brew/@count . У каждого могут быть разные обработчики маршрута.
Динамические веб-сайты

Подождите секунду — во всех предыдущих примерах мы никогда не создавали каталог на жестком диске для хранения этих маршрутов. Короткий ответ: нам не нужно. Все маршруты F3 являются виртуальными. Они не отражают структуру папок нашего жесткого диска. Если у вас есть программы или статические файлы (изображения, CSS и т. Д.), Которые не используют платформу — если пути к этим файлам не конфликтуют с какими-либо маршрутами, определенными в вашем приложении, — программное обеспечение вашего веб-сервера доставит их на сервер. браузер пользователя, если сервер настроен правильно.
Названные маршруты

Когда вы определяете маршрут, вы можете назначить ему имя. Используйте имя маршрута в вашем коде и шаблонах вместо напечатанного URL. Затем, если вам нужно изменить свои URL-адреса, чтобы угодить начальникам по маркетингу, вам нужно только изменить место, где был определен маршрут. Имена маршрутов должны соответствовать правилам именования переменных php (без точек, тире или дефисов).

Назовем маршрут: —

$f3->route(‘GET @beer_list: /beer’, ‘Beer->list’);

Имя вставляется после маршрута VERB (в данном примере GET ), перед которым стоит символ @ , и отделяется от части URL двоеточием : символ. Вы можете вставить пробел после двоеточия, если это облегчает чтение вашего кода (как показано здесь).

Чтобы получить доступ к именованному маршруту в шаблоне, получите значение именованного маршрута в качестве ключа массива ALIASES : —

View beer list

Чтобы перенаправить посетителя на новый URL-адрес, вызовите именованный маршрут внутри метода reroute() например:

// именованный маршрут является строковым значением
$f3->reroute(‘@beer_list’); // обратите внимание на одинарные кавычки

Если вы используете токены в своем маршруте, F3 заменит эти токены их текущим значением. Если вы хотите изменить значение токена перед вызовом перенаправления, передайте его как 2-й аргумент.

$f3->route('GET @beer_list: /beer/@country', 'Beer->bycountry');
$f3->route('GET @beer_list: /beer/@country/@village', 'Beer->byvillage');

 // набор пар ключ-значение передается в качестве аргумента для именованного маршрута
$f3->reroute('@beer_list(@country=Germany)');

 // если требуется более одного токена
$f3->reroute('@beer_list(@country=Germany,@village=Rhine)'); 

Не забудьте urlencode() свои аргументы, если у вас есть символы, которые не соответствуют рекомендациям RFC 1738 для правильно сформированных URL.
Встроенный веб-сервер PHP 5.4

Последняя стабильная версия PHP имеет собственный встроенный веб-сервер. Запустите его, используя следующую конфигурацию: —

 php -S localhost:80 -t /var/www/ 

Приведенная выше команда начнет маршрутизацию всех запросов в корневой каталог /var/www . Если получен входящий HTTP-запрос для файла или папки, PHP будет искать его в корневом веб-каталоге и отправлять его в браузер, если он найден. В противном случае PHP загрузит index.php по умолчанию (содержащий ваш код с поддержкой F3).
Пример конфигурации Apache

Если вы используете Apache, убедитесь, что вы активировали модуль перезаписи URL (mod_rewrite) в файле apache.conf (или httpd.conf). Вы также должны создать файл .htaccess, содержащий следующее: —

 # Включить переписать движок и направить запросы в фреймворк
 RewriteEngine On

 # Некоторые серверы требуют, чтобы вы указали директиву RewriteBase
 # В таких случаях это должен быть путь (относительно корня документа)
 # содержащий этот файл .htaccess
 #
 # RewriteBase /
 
RewriteRule ^(tmp)\/|\.ini$ - [R=404]

RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

Сценарий сообщает Apache, что всякий раз, когда поступает HTTP-запрос и если не удается найти физический файл ( !-f ), путь ( !-d ) или символическую ссылку ( !-l ), он должен передать управление в index.php , который содержит наш главный / фронт-контроллер, который, в свою очередь, вызывает фреймворк.

.htaccess file содержащий директивы Apache, указанные выше, всегда должен находиться в той же папке, что и index.php .

Вам также нужно настроить Apache, чтобы он знал физическое местоположение index.php на вашем жестком диске. Типичная конфигурация:

DocumentRoot "/var/www/html"

    Options -Indexes +FollowSymLinks +Includes
    AllowOverride All
    Order allow,deny
    Allow from All

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

NameVirtualHost *

    ServerName site1.com
    DocumentRoot "/var/www/site1"
    
        Options -Indexes +FollowSymLinks +Includes
        AllowOverride All
        Order allow,deny
        Allow from All
    


    ServerName site2.com
    DocumentRoot "/var/www/site2"
    
        Options -Indexes +FollowSymLinks +Includes
        AllowOverride All
        Order allow,deny
        Allow from All
    

Каждое site1.com site2.com ( site1.com и site2.com в нашем примере) должно быть указано в /etc/hosts . В Windows вы должны отредактировать C:/WINDOWS/system32/drivers/etc/hosts . Перезагрузка может потребоваться, чтобы изменения вступили в силу. Затем вы можете указать свой веб-браузер по адресу http://site1.com или http://site2.com . Виртуальные хосты значительно упрощают развертывание ваших приложений.
Пример конфигурации Nginx

Для серверов Nginx вот рекомендуемая конфигурация (замените ip_address: port на настройки PHP FastCGI вашей среды): —

server {
    root /var/www/html;
    location / {
        index index.php index.html index.htm;
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        fastcgi_pass ip_address:port;
        include fastcgi_params;
    }
}

Пример конфигурации Lighttpd

Серверы Lighttpd настраиваются аналогичным образом:

$HTTP["host"] =~ "www\.example\.com$" {
    url.rewrite-once = ( "^/(.*?)(\?.+)?$"=>"/index.php/$1?$2" )
    server.error-handler-404 = "/index.php"
}

Пример конфигурации IIS

Установите модуль перезаписи URL и соответствующую платформу .NET, соответствующую вашей версии Windows. Затем создайте файл с именем web.config в корне приложения со следующим содержимым:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Application" stopProcessing="true">
          <match url=".*" ignoreCase="false" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
          </conditions>
          <action type="Rewrite" url="index.php" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

перенаправление

Итак, вернемся к кодированию. Вы можете объявить страницу устаревшей и перенаправить посетителей на другой сайт / страницу: —

$f3->route('GET|HEAD /obsoletepage',
    function($f3) {
        $f3->reroute('/newpage');
    }
);

Если кто-то пытается получить доступ к URL-адресу http://www.example.com/obsoletepage используя HTTP GET или HEAD-запрос, платформа перенаправляет пользователя на URL-адрес: http://www.example.com/newpage как показано на приведенный выше пример. Вы также можете перенаправить пользователя на другой сайт, например, $f3->reroute(‘http://www.anotherexample.org/’); ,

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

HTTP перенаправления необходимы, но они также могут быть дорогими. Насколько это возможно, воздержитесь от использования $f3->reroute() для отправки пользователя на другую страницу того же веб-сайта, если вы можете управлять потоком своего приложения, вызывая функцию или метод, который обрабатывает целевой маршрут.

Однако этот подход не изменит URL-адрес в адресной строке веб-браузера пользователя. Если это не то поведение, которое вам нужно, и вам действительно нужно отправить пользователя на другую страницу, например, при успешной отправке формы или после аутентификации пользователя, Fat-Free отправляет HTTP 303 See Other Заголовок HTTP 303 See Other . Для всех других попыток перенаправления на другую страницу или сайт платформа отправляет заголовок HTTP 301 Moved Permanently .
Запуск 404

Во время выполнения Fat-Free автоматически генерирует ошибку HTTP 404 всякий раз, когда обнаруживает, что входящий HTTP-запрос не соответствует ни одному из маршрутов, определенных в вашем приложении. Однако бывают случаи, когда вам нужно запустить его самостоятельно.

Возьмите, например, маршрут, определенный как GET /dogs/@breed . Логика вашего приложения может включать поиск в базе данных и попытку извлечь запись, соответствующую значению @breed во входящем HTTP-запросе. Поскольку Fat-Free будет принимать любое значение после префикса /dogs/ из-за присутствия токена @breed , программное отображение сообщения HTTP 404 Not Found становится необходимым, когда программа не находит соответствия в нашей базе данных. Для этого используйте следующую команду: —

$f3->error(404);

Представительный государственный трансферт (РЕСТ)

Архитектура Fat-Free основана на том, что HTTP URI представляют собой абстрактные веб-ресурсы (не ограничиваясь HTML), и каждый ресурс может переходить из одного состояния приложения в другое. По этой причине F3 не имеет никаких ограничений на то, как вы структурируете свое приложение. Если вы предпочитаете использовать шаблон Model-View-Controller , F3 может помочь вам разделить компоненты приложения, придерживаясь этой парадигмы. С другой стороны, платформа также поддерживает шаблон Resource-Method- Presentation, и реализовать его проще.

Вот пример интерфейса ReST:

class Item {
    function get() {}
    function post() {}
    function put() {}
    function delete() {}
}

$f3=require('lib/base.php');
$f3->map('/cart/@item','Item');
$f3->run();

Метод Fat-Free $f3->map() предоставляет интерфейс ReST, сопоставляя методы HTTP в маршрутах с эквивалентными методами объекта или класса PHP. Если ваше приложение получает входящий HTTP-запрос, такой как GET /cart/123 , Fat-Free автоматически передает управление методу get() объекта или класса. С другой стороны, запрос POST /cart/123 будет перенаправлен в метод post() класса Item .

Примечание. Браузеры не реализуют методы HTTP PUT и DELETE в обычных формах HTML. Эти и другие методы ReST ( HEAD и CONNECT ) доступны только через вызовы AJAX на сервер.

Если инфраструктура получает HTTP-запрос для маршрута, который отображается на метод, который не реализован классом (возможно, вы сделали ошибку в отображении маршрута или метод еще не написан), она генерирует HTTP 405 Method Not Allowed ошибка.

Если клиент запрашивает OPTIONS HTTP для ресурса URL, F3 отвечает соответствующими заголовками HTTP, которые указывают, какие методы разрешены для ресурса (HEAD, GET, PUT и т. Д.). Каркас не будет сопоставлять запрос OPTIONS с классом.
Автозагрузчик F3

Fat-Free позволяет загружать классы только тогда, когда они вам нужны, поэтому они не сжигают больше памяти, чем требуется конкретному сегменту вашего приложения. И вам не нужно писать длинный список операторов include или require только для загрузки классов PHP, сохраненных в разных файлах и разных местах. Фреймворк может сделать это автоматически для вас. Просто сохраните ваши файлы (один класс на файл) в папке и скажите платформе, чтобы автоматически загружать соответствующий файл, когда вы вызываете метод в классе: —

$f3->set('AUTOLOAD','autoload/');

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

$f3->set('AUTOLOAD','admin/autoload/; user/autoload/; default/'); 

Важное замечание: За исключением расширения .php, имя класса и имя файла должны быть идентичны, чтобы инфраструктура правильно загружала ваш класс. Базовое имя этого файла должно совпадать с вызовом вашего класса, например, F3 будет искать либо Foo/BarBaz.php либо foo/barbaz.php когда обнаружит new Foo\BarBaz оператор new Foo\BarBaz в вашем приложении.

Работа с пространствами имен

AUTOLOAD позволяет иерархиям классов находиться в подпапках с одинаковыми именами, поэтому если вы хотите, чтобы инфраструктура автоматически загружала класс пространств имен PHP 5.4, который вызывается следующим образом: —

$f3->set('AUTOLOAD','autoload/');
$obj=new Gadgets\iPad;

Вы можете создать иерархию папок, которая соответствует той же структуре. Предполагая, что /var/www/html/ является вашим веб-корнем, F3 будет искать класс в /var/www/html/autoload/gadgets/ipad.php . Файл ipad.php должен иметь следующий минимальный код: —

namespace Gadgets;
class iPad {}

Помните: все имена каталогов в Fat-Free должны заканчиваться косой чертой. Вы можете назначить путь поиска для автозагрузчика следующим образом: —

$f3->set('AUTOLOAD','main/;aux/');

Маршрутизация к классу пространства имен

F3, будучи интегрированной с пространством имен структурой, позволяет использовать метод в классе пространства имен в качестве обработчика маршрута, и есть несколько способов сделать это. Чтобы вызвать статический метод:

$f3->set('AUTOLOAD','classes/');
$f3->route('GET|POST /','Main\Home::show');

Приведенный выше код вызовет статический метод show() класса Home в пространстве имен Main . Класс Home должен быть сохранен в папке classes/main/home.php для его автоматической загрузки.

Если вы предпочитаете работать с объектами: —

$f3->route('GET|POST /','Main\Home->show'); 

создаст экземпляр класса Home во время выполнения и после этого вызовет метод show() .

Обработчики событий

В F3 есть пара приемников событий маршрутизации, которые могут помочь вам улучшить поток и структуру классов контроллеров. Скажем, у вас есть маршрут, определенный следующим образом:

$f3->route('GET /','Main->home'); 

Если приложение получает HTTP-запрос, соответствующий указанному выше маршруту, F3 создает экземпляр Main , но перед выполнением метода home() платформа ищет метод в этом классе с именем beforeRoute() . В случае обнаружения F3 запускает код, содержащийся в обработчике события beforeRoute() перед передачей управления методу home() . Как только это будет выполнено, платформа ищет обработчик события afterRoute() . Как и beforeRoute() , метод выполняется, если он определен.

Динамические обработчики маршрутов

Вот еще одна вкусняшка F3: —

$f3->route('GET /products/@action','Products->@action'); 

Если ваше приложение получит запрос, скажем, на /products/itemize , F3 извлечет строку ‘itemize’ из URL-адреса и передаст ее @action в обработчике маршрута. Затем F3 будет искать класс с именем Products и выполнять метод itemize() .

Обработчики динамических маршрутов могут иметь различные формы:

// static method
$f3->route('GET /public/@genre','Main::@genre');
// object mode
$f3->route('GET /public/@controller/@action','@controller->@action');

F3 вызывает ошибку HTTP 404 Not Found во время выполнения, если он не может передать управление классу или методу, связанному с текущим маршрутом, то есть неопределенному классу или методу.

AJAX и синхронные запросы

Шаблоны маршрутизации могут содержать модификаторы, которые предписывают платформе основывать свое решение о маршрутизации на типе HTTP-запроса:

$f3->route('GET /example [ajax]','Page->getFragment');
$f3->route('GET /example [sync]','Page->getFull'); 

Первый оператор направит HTTP-запрос к Page->getFragment() только если сервер получил заголовок X-Requested-With: XMLHttpRequest (объект AJAX). Если обнаружен обычный (синхронный) запрос, F3 просто перейдет к следующему сопоставленному шаблону, и в этом случае он выполнит Page->getFull() .

Если в шаблоне маршрутизации не определены модификаторы, то и AJAX, и синхронные типы запросов направляются указанному обработчику.

Модификаторы шаблонов маршрутов также распознаются $f3->map().

Рамочные переменные

Основное использование.

Переменные, определенные в Fat-Free, являются глобальными, то есть к ним может обращаться любой компонент MVC. Фреймворковые глобалы не идентичны PHP глобальным. Переменная F3 с именем content не идентична переменной $content в PHP. F3 сам по себе является предметно-ориентированным языком и поддерживает свою собственную таблицу символов для системных переменных и переменных приложения.
Фреймворк, как и любая хорошо спроектированная объектно-ориентированная программа, не загрязняет глобальное пространство имен PHP константами, переменными, функциями или классами, которые могут конфликтовать с любым приложением. В отличие от других платформ, F3 не использует оператор PHP define() . Все каркасные константы ограничены классами.

Чтобы назначить значение переменной без жира:

$f3->set('var',value); // или
$f3->var=value;

$f3->set('hello.world','good morning');  // переводится в: 'hello' == массив ('world' => 'доброе утро')
$f3->{'hello.world'}='good morning';  // то же, что и в предыдущем заявлении 

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

Чтобы установить несколько переменных одновременно:

$f3->mset(
    [
        'foo'=>'bar',
        'baz'=>123
    ]
); 

Чтобы получить значение переменной структуры с именем var : —

echo $f3->get('var'); // or
echo $f3->var;

Чтобы удалить переменную Fat-Free из памяти, если она вам больше не нужна (откажитесь от нее, чтобы она не мешала другим вашим функциям / методам), используйте метод: —

$f3->clear('var'); // or
unset($f3->var);

Чтобы узнать, была ли переменная определена ранее:

$f3->exists('var') //
isset($f3->var)

Глобальные переменные

F3 поддерживает свою собственную таблицу символов для переменных каркаса и приложения, которые не зависят от PHP. Некоторые переменные отображаются в глобальные переменные PHP. Сессия Fat-Free эквивалентна $_SESSION , а REQUEST отображается на $_REQUEST . Рекомендуется использовать каркасные переменные вместо PHP, чтобы помочь вам в передаче данных между различными функциями, классами и методами. У них также есть другие преимущества:

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

Fat-Free не поддерживает только тупое хранилище для переменных и их значений. Он также может автоматизировать управление сессиями и другие вещи. Присвоение или получение значения через переменную SESSION F3 автоматически запускает сеанс. Если вы используете $_SESSION (или функции, связанные с сеансами) напрямую, вместо переменной среды SESSION , ваше приложение становится ответственным за управление сеансами.

Как правило, каркасные переменные не сохраняются между HTTP-запросами.Только SESSIONи COOKIE(и их элементы), которые сопоставляются с PHP $_SESSIONи $_COOKIEглобальными переменными, освобождаются от HTTP-статуса без состояния.

Есть несколько предопределенных глобальных переменных, используемых Fat-Free внутри, и вы, безусловно, можете использовать их в своем приложении. Убедитесь, что вы знаете, что делаете. Изменение некоторых глобальных переменных без жира может привести к неожиданному поведению платформы.

Фреймворк имеет несколько переменных, которые помогут вам организовать ваши файлы и структуры каталогов. Мы видели, как мы можем автоматизировать загрузку классов с помощью AUTOLOAD. Существует UIглобальная переменная, которая содержит путь, указывающий на местоположение ваших HTML-представлений / шаблонов. DEBUGэто еще одна переменная, которую вы будете использовать довольно часто во время разработки приложения, и она используется для настройки многословности трассировки ошибок.

Обратитесь к Краткому справочнику, если вам нужен полный список встроенных переменных структуры.
Правила именования

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

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

Вы не должны использовать PHP зарезервированные слова , как if, for, class, defaultи т.д. в качестве имен переменных рамочные. Это может привести к непредсказуемым результатам.
Работа со строковыми и массивными переменными

F3 также предоставляет ряд инструментов, которые помогут вам с переменными каркаса.

$f3->set('a','fire');
$f3->concat('a','cracker');
echo $f3->get('a'); // возвращает строку «firecracker»

$f3->copy('a','b');
echo $f3->get('b'); // возвращает ту же строку: 'firecracker' 

F3 также предоставляет несколько примитивных методов для работы с переменными массива:

$f3->set('colors',['red','blue','yellow']);
$f3->push('colors','green'); // работает как PHP array_push() 
echo $f3->pop('colors'); // возвращает «зеленый»

$f3->unshift('colors','purple'); // аналогично array_unshift () 
echo $f3->shift('colors'); // возвращает 'фиолетовый'

$f3->set('grays',['light','dark']);
$result=$f3->merge('colors','grays'); // объединяет два массива 

Самостоятельные структуры каталогов

В отличие от других структур, которые имеют жесткую структуру папок, F3 дает вам большую гибкость. Вы можете иметь структуру папок, которая выглядит следующим образом (заключенные в скобки слова в заглавных буквах представляют переменные среды F3, которые необходимо настроить): —

/ (your Web root, where index.php is located)
app/ (application files)
    dict/ (LOCALES, optional)
    controllers/
    logs/ (LOGS, optional)
    models/
    views/ (UI)
css/
js/
lib/ (you can store base.php here)
tmp/ (TEMP, used by the framework)
   cache/ (CACHE)

Не стесняйтесь организовывать свои файлы и каталоги любым удобным для вас способом. Просто установите соответствующие глобальные переменные F3. Если вы хотите действительно безопасный сайт, Fat-Free даже позволяет хранить все ваши файлы в недоступном для Интернета каталоге. Единственное требование состоит в том , что вы оставите index.php, .htaccessи ваши общедоступные файлы, такие как CSS, JavaScript, изображения и т.д. в пути видна в вашем браузере.
Об обработчике ошибок F3

Fat-Free генерирует свои собственные страницы ошибок HTML со следами стека, чтобы помочь вам с отладкой. Вот пример:

Внутренняя ошибка сервера

strpos() expects at least 2 parameters, 0 given

• var/html/dev/main.php:96 strpos()
• var/html/dev/index.php:16 Base->run()

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

$f3->set('ONERROR',
    function($f3) {
        // custom error handler code goes here
        // use this if you want to display errors in a
        // format consistent with your site's theme
        echo $f3->get('ERROR.status');
    }
);

F3 поддерживает глобальную переменную, содержащую сведения о последней ошибке, произошедшей в вашем приложении. ERRORПеременная является массивом структурирована следующим образом : —

ERROR.code - displays the error code (404, 500, etc.)
ERROR.status - header and page title
ERROR.text - error context
ERROR.trace - stack trace

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

$f3->set('DEBUG',3);

Просто вставьте команду в последовательность загрузки вашего приложения.

Как только ваше приложение будет готово к выпуску, просто удалите заявление из вашего приложения или замените его следующим:

$f3->set('DEBUG',0);

Это подавит вывод трассировки стека на любой сгенерированной системой странице ошибки HTML (потому что она не предназначена для просмотра посетителями вашего сайта).

DEBUG может иметь значения в диапазоне от 0 (трассировка стека подавлена) до 3 (наиболее многословно).

Не забывайТрассировки стека могут содержать пути, имена файлов, команды базы данных, имена пользователей и пароли. Вы можете подвергнуть свой веб-сайт излишним угрозам безопасности, если вам не удастся установить для DEBUGглобальной переменной значение 0 в производственной среде.
Конфигурационные файлы

Если ваше приложение должно быть настраиваемым пользователем, F3 предоставляет удобный метод для чтения файлов конфигурации для настройки вашего приложения. Таким образом, вы и ваши пользователи могут настроить приложение, не изменяя код PHP.

Вместо создания сценария PHP, который содержит следующий пример кода:

$f3->set('num',123);
$f3->set('str','abc');
$f3->set('hash',['x'=>1,'y'=>2,'z'=>3]);
$f3->set('items',[7,8,9]);
$f3->set('mix',['this',123.45,FALSE]);

Вы можете создать файл конфигурации, который делает то же самое:

[globals]
num = 123
 ; это обычная строка 
str = abc
 ; другой способ назначения строк 
str = " abc "
 ; это массив
hash[x]=1
hash[y]=2
hash[z]=3
 ; точка-нотация тоже распознается 
hash.x = 1
hash.y = 2
hash.z = 3
; это тоже массив 
items=7,8,9
 ; массив со смешанными элементами 
mix="this",123.45,FALSE

Вместо длинных $f3->set()операторов в вашем коде вы можете указать платформе загрузить файл конфигурации в качестве замены кода. Давайте сохраним приведенный выше текст как setup.cfg. Затем мы можем назвать это простым:

$f3->config('setup.cfg');

Строковые значения не нужно заключать в кавычки, если только вы не хотите, чтобы в них были начальные или конечные пробелы. Если запятую следует рассматривать как часть строки, заключите строку в двойные кавычки — в противном случае значение будет считаться массивом (запятая используется как разделитель элементов массива). Строки могут занимать несколько строк: —

[globals] 
str = " это 
очень длинная 
строка " 

F3 также дает вам возможность определять маршруты HTTP в файлах конфигурации:

[routes]
GET /=home
GET /404=App->page404
GET /page/@num=Page->@controller

Карты маршрутов также могут быть определены в конфигурационных файлах: —

[maps]
/blog=Blog\Login
/blog/@controller=Blog\@controller

[globals], [routes]И [maps]заголовки разделов необходимы. Вы можете объединить оба раздела в одном файле конфигурации — хотя рекомендуется иметь [routes]и [maps]в отдельном файле. Таким образом, вы можете позволить конечным пользователям изменять некоторые специфичные для приложения флаги и в то же время ограничивать их вмешательство в логику маршрутизации.

Представления и шаблоны

Разделение сущностей.

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

в,

не должна требовать изменения в коде вашего приложения. Таким же образом, превращая простой маршрут , как GET /aboutк GET /about-usне должны иметь никакого влияния на ваш пользовательский интерфейс и бизнес — логики, (вид и модель в MVC, или представление и метод в РМР).

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

F3 поддерживает PHP как шаблонизатор. Посмотрите на этот фрагмент HTML, сохраненный как template.htm: -.

Hello, !

Если на вашем сервере включены короткие теги, это тоже должно работать:

Hello,

Чтобы отобразить этот шаблон, вы можете иметь код PHP, который выглядит следующим образом (хранится в файле, отдельном от шаблона): —

$f3=require('lib/base.php');
$f3->route('GET /',
    function($f3) {
        $f3->set('name','world');
        $view=new View;
        echo $view->render('template.htm');
        // Previous two lines can be shortened to:-
        // echo View::instance()->render('template.htm');
    }
);
$f3->run();

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

Быстрый взгляд на язык шаблонов F3

В качестве альтернативы PHP вы можете использовать собственный шаблонизатор F3. Приведенный выше фрагмент HTML можно переписать так:

Hello, {{ @name }}!

и код, необходимый для просмотра этого шаблона: —

$f3=require('lib/base.php');
$f3->route('GET /',
    function($f3) {
        $f3->set('name','world');
        $template=new Template;
        echo $template->render('template.htm');
        // Above lines can be written as:-
        // echo Template::instance()->render('template.htm');
    }
);
$f3->run();

Подобно токенам маршрутизации, используемым для перехвата переменных в URL (все еще помните GET /brew/@countпример из предыдущего раздела?), Токены шаблона F3 начинаются с @символа, за которым следует ряд букв и цифр, заключенных в фигурные скобки. Первый символ должен быть альфа. Шаблонные токены имеют непосредственное соответствие с переменными каркаса. Каркас автоматически заменяет токен значением, хранящимся в переменной с тем же именем.

В нашем примере F3 заменяет @nameтокен в нашем шаблоне значением, которое мы присвоили переменной name. Во время выполнения вывод приведенного выше кода будет:

Hello, world

Беспокоитесь о производительности шаблонов F3? Во время выполнения платформа анализирует и компилирует / конвертирует шаблон F3 в код PHP при первом его отображении $template->render(). Фреймворк затем использует этот скомпилированный код во всех последующих вызовах. Следовательно, производительность должна быть такой же, как у шаблонов PHP, если не лучше из-за оптимизации кода, выполняемой компилятором шаблонов, когда задействованы более сложные шаблоны.

Используете ли вы шаблонный движок PHP или собственный F3, рендеринг шаблонов может быть значительно быстрее, если на вашем сервере есть APC, WinCache или XCache.

Как упоминалось ранее, переменные каркаса могут содержать любой тип данных PHP. Однако использование нескалярных типов данных в шаблонах F3 может привести к странным результатам, если вы не будете осторожны. Выражения в фигурных скобках всегда будут оцениваться и преобразовываться в строку. Вы должны ограничить переменные пользовательский интерфейс для простых скаляров: — string, integer, booleanили floatтипов данных.

Но как насчет массивов? Fat-Free распознает массивы, и вы можете использовать их в своих шаблонах. Вы можете слепить что-то вроде: —

{{ @buddy[0] }}, {{ @buddy[1] }}, and {{ @buddy[2] }}

И заполните @buddyмассив в вашем PHP-коде, прежде чем обслуживать шаблон: —

$f3->set(‘buddy’,[‘Tom’,’Dick’,’Harry’]);

Однако, если вы просто вставите {{ @buddy }}в свой шаблон, PHP 5.4 заменит его, ‘Array’ потому что он преобразует токен в строку. PHP 5.4, с другой стороны, будет генерировать Array to string conversionуведомление во время выполнения.

F3 позволяет встраивать выражения в шаблоны. Эти выражения могут принимать различные формы, такие как арифметические вычисления, логические выражения, константы PHP и т. Д. Вот несколько примеров:

{{ 2*(@page-1) }}
{{ (int)765.29+1.2e3 }}

{{ var_dump(@xyz) }}

That is {{ preg_match('/Yes/i',@response)?'correct':'wrong' }}!

{{ @obj->property }}

Дополнительное примечание о выражениях массива: обратите внимание, что @foo.@barэто конкатенация строк $foo.$bar), тогда как @foo.barпереводится как $foo[‘bar’]. Если $foo[$bar]это то, что вы хотели, используйте @foo[@bar]обычные обозначения.

Каркасные переменные также могут содержать анонимные функции:

$f3->set('func',
    function($a,$b) {
        return $a.', '.$b;
    }
);

Механизм шаблонов F3 будет интерпретировать токен, как ожидается, если вы укажете следующее выражение:

{{ @func(‘hello’,’world’) }}

Шаблоны внутри шаблонов

Простая замена переменных — это то, что есть во всех шаблонизаторах. У Fat-Free больше рукавов: —

Директива будет встраивать содержимое шаблона header.htm в точное место, где указана директива. Вы также можете иметь динамический контент в виде: —

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

 // переключаем контент на ваш суб-шаблон блога 
$f3->set('content','blog.htm'); 
// по другому маршруту, переключаем контент в под-шаблон вики 
$f3->set('content','wiki.htm'); 

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

Вы можете указать имена файлов с чем-то иным, чем расширения .htm или .html, но их проще предварительно просмотреть в веб-браузере на этапе разработки и отладки. Шаблонный движок не ограничивается рендерингом файлов HTML. Фактически вы можете использовать шаблонизатор для рендеринга других типов файлов.

Директива также имеет необязательный ifатрибут , так что вы можете указать условие , которое должно быть выполнено до того , как суб-шаблон вставляется: —

Исключение сегментов

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


    

Кусок HTML, который мы не хотим отображать в данный момент

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

Вот еще один способ исключения содержимого шаблона или добавления комментариев: —

{*

Кусок HTML, который мы не хотим отображать в данный момент

*}

Условные сегменты

Другая полезная функция шаблона — это директива. Позволяет встраивать фрагмент HTML в зависимости от оценки определенного условия. Вот несколько примеров:-


     Вставляется, если условие ложно  


    
        < div > Появляется, когда условие выполняется 
    
    
        < div > Появляется, когда условие ложно 
    

Вы можете иметь столько вложенных директив, сколько вам нужно.

Автоматически вызывается выражение F3 внутри атрибута if, равного NULLпустой строке, логическому значению FALSE, пустому массиву или нулю . Если в вашем шаблоне нет блока, то открывающий и закрывающий теги необязательны: —


    

HTML-блок, который будет включен, если условие выполнено

Повторяющиеся сегменты

Fat-Free также может обрабатывать повторяющиеся блоки HTML: —


    

{{ trim(@fruit) }}

groupАтрибут @fruitsвнутри директивы должен быть массивом и должен быть установлен в вашем PHP кода соответственно: —

$f3->set(‘fruits’,[‘apple’,’orange ‘,’ banana’]);

Ничего не получается, присваивая значение @fruitв коде вашего приложения. Fat-Free игнорирует любое заданное значение, которое может иметь, поскольку использует переменную для представления текущего элемента во время итерации по группе. Вывод вышеупомянутого фрагмента шаблона HTML и соответствующего кода PHP становится:

apple

orange

banana

Каркас позволяет неограниченное вложение блоков: —


    

{{ @ikey }}

{{ @ispan }}

Примените следующую команду F3: —

$f3->set('div',
    [
        'coffee'=>['arabica','barako','liberica','kopiluwak'],
        'tea'=>['darjeeling','pekoe','samovar']
    ]
);

В результате вы получите следующий HTML-фрагмент:

coffee

arabica barako liberica kopiluwak

tea

darjeeling pekoe samovar

Удивительно, не правда ли? And the only thing you had to do in PHP was to define the contents of a single F3 variable div to replace the @div token. Fat-Free makes both programming and Web template design really easy.

В шаблонной директиве valueатрибут возвращает значение текущего элемента в итерации. Если вам нужно получить ключ массива текущего элемента, используйте keyвместо этого атрибут. keyАтрибут является необязательным.

также имеет необязательный атрибут counter, который можно использовать следующим образом:


    

{{ trim(@fruit) }}

Внутренне механизм шаблонов F3 записывает количество итераций цикла и сохраняет это значение в переменной / токене @ctr, которая используется в нашем примере для определения нечетной / четной классификации.

Встраивание JavaScript и CSS

Если вам нужно вставить токены F3 внутри

Внедрение шаблонных директив в ваши теги

Кодировка документа

По умолчанию Fat-Free использует набор символов UTF-8, если не был изменен. Вы можете изменить это поведение, выполнив что-то вроде: -

$f3->set('ENCODING','ISO-8859-1');

Как только вы сообщите структуре желаемого набора символов, F3 будет использовать его во всех шаблонах HTML и XML, пока не будет снова изменено.
Все виды шаблонов

Как упоминалось ранее в этом разделе, платформа не ограничивается шаблонами HTML. Вы можете также обрабатывать шаблоны XML. Механика очень похожа. У вас еще есть то же самое {{ @variable }}и {{ expression }}жетоны, , , , и директивы в вашем распоряжении. Просто скажите F3, что вы передаете XML-файл вместо HTML:

echo Template::instance()->render('template.xml','application/xml');

Второй аргумент представляет тип MIME отображаемого документа.

Компонент View MVC охватывает все, что не подпадает под модель и контроллер, что означает, что ваша презентация может и должна включать все виды пользовательских интерфейсов, таких как RSS, электронная почта, RDF, FOAF, текстовые файлы и т. Д. Пример ниже показано, как отделить презентацию электронной почты от бизнес-логики приложения: -

MIME-Version: 1.0
Content-type: text/html; charset={{ @ENCODING }}
From: {{ @from }}
To: {{ @to }}
Subject: {{ @subject }}

Добро пожаловать и спасибо, что присоединились к {{@site}}!

Сохраните вышеуказанный шаблон электронной почты как welcome.txt. Соответствующий код F3 будет:

$f3->set('from','');
$f3->set('to','');
$f3->set('subject','Welcome');
ini_set('sendmail_from',$f3->get('from'));
mail(
    $f3->get('to'),
    $f3->get('subject'),
    Template::instance()->render('email.txt','text/html')
); 

Совет: Замените функцию SMTP mail () на imap_mail (), если ваш скрипт взаимодействует с сервером IMAP.

Разве это не что-то? Конечно, если у вас есть группа получателей электронной почты, вы будете использовать базу данных для заполнения токенов firstName, lastName и email.

Вот альтернативное решение, использующее плагин SMTP в F3:

$mail=new SMTP('smtp.gmail.com',465,'SSL','account@gmail.com','secret');
$mail->set('from','');
$mail->set('to','"Slasher" ');
$mail->set('subject','Welcome');
$mail->send(Template::instance()->render('email.txt')); 

Многоязычная поддержка

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

Сначала создайте файл словаря со следующей структурой (один файл на язык):

'I love F3',
    'today'=>'Today is {0,date}',
    'pi'=>'{0,number}',
    'money'=>'Amount remaining: {0,number,currency}'
];

Сохранить как dict/en.php. Давайте создадим еще один словарь, на этот раз для немецкого языка. Сохраните файл как dict/de.php: -

'Ich liebe F3',
    'today'=>'Heute ist {0,date}',
    'money'=>'Restbetrag: {0,number,currency}'
];

Словари - это не что иное, как пары ключ-значение. F3 автоматически создает переменные среды на основе ключей в языковых файлах. Таким образом, эти переменные легко встроить в токены в шаблоны. Используя шаблонный движок F3: -

{{ @love }}

{{ @today,time() | format }}.
{{ @money,365.25 | format }}
{{ @pi }}

>

И более длинная версия, которая использует PHP в качестве движка шаблонов:


get('love'); ?>

get('today',time()); ?>.
get('money',365.25); ?> get('pi'); ?>

Далее мы инструктируем F3 искать словари в dict/папке: -

$f3->set('LOCALES','dict/');

Но как фреймворк определяет, какой язык использовать? F3 обнаружит его автоматически, сначала посмотрев заголовки HTTP-запросов, в частности Accept-Languageзаголовок, отправленный браузером.

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

$f3->set('LANGUAGE','de');

Примечание. В приведенном выше примере ключ pi существует только в словаре английского языка. Фреймворк всегда будет использовать English ( en) как запасной вариант для заполнения ключей, которые отсутствуют на указанном (или обнаруженном) языке.

Вы также можете создавать файлы словарей для языковых вариантов, например en-US, es-ARи т. Д. В этом случае F3 сначала будет использовать языковой вариант (например es-AR). Если в варианте есть ключи, которых не существует, платформа будет искать ключ в корневом языке ( es), а затем использовать enязыковой файл в качестве окончательного запасного варианта. Пары ключ-значение словаря становятся переменными F3 после обращения к ним. Убедитесь , что ключи не конфликтует ни с рамочным переменной реализованным с помощью $f3->set(), $f3->mset()или $f3->config().

Вы заметили своеобразную 'Today is {0,date}'картину в нашем предыдущем примере? Многоязычность F3 зависит от правил форматирования строк / сообщений проекта ICU. Платформа использует свое собственное подмножество реализации форматирования строки ICU. Нет необходимости intlактивировать расширение PHP на сервере.

Еще одна вещь: F3 может также загрузить отформатированные файлы в стиле .ini в виде словарей: -

love="I love F3"
today="Today is {0,date}"
pi="{0,number}"
money="Общая сумма: {0,number,currency}"" 

Сохраните его, dict/en.iniчтобы фреймворк мог загрузить его автоматически.

Санация данных

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

$f3->set('ESCAPE',FALSE);

Это может иметь нежелательные последствия. Возможно, вы не захотите, чтобы все переменные проходили через неэкранированные. Fat-Free позволяет вам удалять переменные индивидуально. Для шаблонов F3: -

{{ @html_content | raw }}

В случае шаблонов PHP: -

raw($html_content); ?>

В дополнение к автоматическому экранированию переменных F3, платформа также дает вам свободу действий при дезинфекции пользовательского ввода из HTML-форм:

$f3->scrub($_GET,'p; br; span; div; a');

Эта команда удалит все теги (кроме указанных во втором аргументе) и небезопасные символы из указанной переменной. Если переменная содержит массив, каждый элемент в массиве рекурсивно очищается. Если в качестве второго аргумента передается звездочка (*), $f3->scrub()все теги HTML разрешаются без изменений и просто удаляются небезопасные управляющие символы.

Базы данных

Подключение к базе данных Engine

Fat-Free предназначен для упрощения взаимодействия с базами данных SQL. Если вы не из тех, кто хочет погрузиться в детали SQL, но больше ориентируетесь на объектно-ориентированную обработку данных, вы можете перейти непосредственно к следующему разделу этого руководства. Тем не менее, если вам нужно выполнить некоторые сложные задачи по обработке данных и оптимизации производительности базы данных, SQL - это путь.

Установление связи с механизмом SQL, таким как MySQL, SQLite, SQL Server, Sybase и Oracle, выполняется с помощью знакомой $f3->set()команды. Подключение к базе данных SQLite будет:

$db=new DB\SQL('sqlite:/absolute/path/to/your/database.sqlite');

Другой пример, на этот раз с MySQL:

$db=new DB\SQL(
    'mysql:host=localhost;port=3306;dbname=mysqldb',
    'admin',
    'p455w0rD'
);

Запрос к базе данных

ХОРОШО. Это было легко, не так ли?Это почти то же самое, что вы сделали бы то же самое в обычном PHP. Вам просто нужно знать формат DSN базы данных, к которой вы подключаетесь. Смотрите раздел PDO руководства по PHP.

Давайте продолжим наш код PHP: -

$f3->set('result',$db->exec('SELECT brandName FROM wherever'));
echo Template::instance()->render('abc.htm');

Да, что здесь происходит? Разве мы не должны настраивать такие вещи, как PDO, операторы, курсоры и т. Д.? Ответ прост: вам не нужно. F3 упрощает все, заботясь обо всей тяжелой работе в бэкэнде.

На этот раз мы создаем такой шаблон HTML, abc.htmкоторый имеет как минимум следующее:


    {{ @item.brandName  }}

В большинстве случаев набора команд SQL должно быть достаточно для создания готового к веб-результатам результата, чтобы вы могли resultнапрямую использовать переменную массива в своем шаблоне. Как бы то ни было, Fat-Free не помешает вам проникнуть во внутренности своего обработчика SQL. Фактически, DB\SQLкласс F3 является производным от PDOкласса PHP , поэтому у вас все еще есть доступ к базовым компонентам PDO и примитивам, задействованным в каждом процессе, если вам нужен какой-то точный контроль.
операции

Вот еще один пример.Вместо одного оператора, предоставленного в качестве аргумента $db->exec()команды, вы также можете передать массив операторов SQL:

$db->exec(
    [
        'DELETE FROM diet WHERE food="cola"',
        'INSERT INTO diet (food) VALUES ("carrot")',
        'SELECT * FROM diet'
    ]
);

F3 достаточно умен, чтобы знать, что если вы передаете массив инструкций SQL, это указывает на пакетную транзакцию SQL. Вам не нужно беспокоиться об откатах и ​​фиксациях SQL, потому что платформа автоматически вернется в исходное состояние базы данных, если во время транзакции произойдет какая-либо ошибка. В случае успеха F3 фиксирует все изменения, внесенные в базу данных.

Вы также можете запустить и завершить транзакцию программно:

$db->begin();
$db->exec('DELETE FROM diet WHERE food="cola"');
$db->exec('INSERT INTO diet (food) VALUES ("carrot")');
$db->exec('SELECT * FROM diet');
$db->commit(); 

Откат произойдет, если в каком-либо из операторов возникнет ошибка.

Чтобы получить список всех выданных инструкций базы данных: -

echo $db->log();

Параметризованные запросы

Передача строковых аргументов в операторы SQL чревата опасностью. Учти это:-

$db->exec(
    'SELECT * FROM users '.
    'WHERE username="'.$f3->get('POST.userID'.'"')
);

Если POSTпеременная userIDне проходит никакой обработки данных, злоумышленник может передать следующую строку и нанести непоправимый ущерб вашей базе данных:

admin"; DELETE FROM users; SELECT "1

К счастью, параметризованные запросы помогают снизить риски: -

$db->exec(
    'SELECT * FROM users WHERE userID=?',
    $f3->get('POST.userID')
);

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

Наш пример в предыдущем разделе будет намного безопаснее от внедрения SQL, если написано так:

$db->exec(
    [
        'DELETE FROM diet WHERE food=:name',
        'INSERT INTO diet (food) VALUES (?)',
        'SELECT * FROM diet'
    ],
    [
        array(':name'=>'cola'),
        array(1=>'carrot'),
        NULL
    ]
);

CRUD (но с большим количеством стиля)

F3 упакован простыми в использовании объектно-реляционными сопоставителями (ORM), которые находятся между вашим приложением и вашими данными, что значительно упрощает и ускоряет процесс написания программ, которые выполняют общие операции с данными, такие как создание, получение, обновление, и удаление (CRUD) информации из баз данных SQL и NoSQL. Преобразователи данных выполняют большую часть работы, сопоставляя взаимодействия объектов PHP с соответствующими внутренними запросами.

Предположим, у вас есть база данных MySQL, содержащая таблицу пользователей вашего приложения. (SQLite, PostgreSQL, SQL Server, Sybase будут делать то же самое.) Он был бы создан с помощью следующей команды SQL: -

CREATE TABLE users (
    userID VARCHAR(30),
    password VARCHAR(30),
    visits INT,
    PRIMARY KEY(userID)
);

Примечание: MongoDB является ядром базы данных NoSQL и по своей сути не требует схем. F3 имеет свою собственную быструю и легкую реализацию NoSQL под названием Jig, которая использует сериализованные PHP-файлы или плоские JSON-кодированные файлы. Эти уровни абстракции не требуют жестких структур данных. Поля могут варьироваться от одной записи к другой. Они также могут быть определены или отброшены на лету.

Теперь вернемся к SQL. Сначала мы устанавливаем связь с нашей базой данных.

$db=new DB\SQL(
    'mysql:host=localhost;port=3306;dbname=mysqldb',
    'admin',
    'wh4t3v3r'
); 

Чтобы получить запись из нашей таблицы: -

$user=new DB\SQL\Mapper($db,'users');
$user->load(['userID=?','tarzan']);

Первая строка создает экземпляр объекта отображения данных, который взаимодействует с usersтаблицей в нашей базе данных. За сценой F3 извлекает структуру usersтаблицы и определяет, какие поля (поля) определены как первичные ключи. На этом этапе объект mapper еще не содержит данных (сухое состояние), поэтому он $userпредставляет собой не что иное, как структурированный объект, но содержит методы, необходимые для выполнения основных операций CRUD, и некоторые дополнительные функции. Чтобы извлечь запись из нашей таблицы пользователей с userIDполем, содержащим строковое значение tarzan, мы используем load() method. Этот процесс называется «автоматическим увлажнением» объекта отображения данных.

Легко, не так ли? F3 понимает, что таблица SQL уже имеет структурное определение, существующее в самой базе данных. В отличие от других сред, F3 не требует никаких дополнительных объявлений классов (если только вы не хотите расширять средства отображения данных, чтобы они соответствовали сложным объектам), никаких избыточных отображений PHP-массива / свойств объекта в поле (дублирование усилий), никаких генераторов кода (для которых требуется код). регенерация, если структура базы данных изменяется), нет глупых файлов XML / YAML для настройки ваших моделей, нет лишних команд только для извлечения одной записи. С F3 простое изменение размера varcharполя в MySQL не требует изменения в коде вашего приложения. В соответствии с MVC и «разделением интересов» администратор базы данных имеет столько же контроля над данными (и структурами), сколько дизайнер шаблонов имеет над шаблонами HTML / XML.

Если вы предпочитаете работать с базами данных NoSQL, сходство в синтаксисе запросов является поверхностным. В случае отображения данных MongoDB, эквивалентный код будет:

$db=new DB\Mongo('mongodb://localhost:27017','testdb');
$user=new DB\Mongo\Mapper($db,'users');
$user->load(['userID'=>'tarzan']); ]); 

С Jig синтаксис похож на шаблонизатор F3:

$db=new DB\Jig('db/data/',DB\Jig::FORMAT_JSON);
$user=new DB\Jig\Mapper($db,'users');
$user->load(['@userID=?','tarzan']);

Smart SQL ORM

Фреймворк автоматически отображает поле visitsв нашей таблице на свойство отображения данных во время создания объекта, т.е.$user=new DB\SQL\Mapper($db,'users'); ,После того , как объект создан, $user->passwordи $user->userIDотображался бы к passwordи userIDполей в нашей таблице, соответственно.

Вы не можете добавить или удалить сопоставленное поле или изменить структуру таблицы, используя ORM. Вы должны сделать это в MySQL или в любом другом движке базы данных, который вы используете. После внесения изменений в ядро ​​базы данных Fat-Free автоматически синхронизирует новую структуру таблицы с вашим объектом отображения данных при запуске приложения.

F3 получает структуру отображения данных непосредственно из схемы базы данных. Нет догадок. Он понимает различия между движками баз данных MySQL, SQLite, MSSQL, Sybase и PostgreSQL.

Идентификаторы SQL не должны использовать зарезервированные слова, и должен быть ограничен буквенно - цифровых символов AZ, 0-9и символ подчеркивания ( _). Имена столбцов, содержащие пробелы (или специальные символы) и заключенные в кавычки в определении данных, не совместимы с ORM. Они не могут быть правильно представлены как свойства объекта PHP.

Допустим, мы хотим увеличить количество посещений пользователя и обновить соответствующую запись в нашей таблице пользователей, мы можем добавить следующий код: -

$user->visits++;
$user->save();

Если мы хотим вставить запись, мы следуем этому процессу:

$user=new DB\SQL\Mapper($db,'users');
// or $user=new DB\Mongo\Mapper($db,'users');
// or $user=new DB\Jig\Mapper($db,'users');
$user->userID='jane';
$user->password=password_hash('secret', PASSWORD_BCRYPT, [ 'cost' => 12 ]);
$user->visits=0;
$user->save();

Мы все еще используем тот же save()метод. Но как F3 узнает, когда запись должна быть вставлена ​​или обновлена? В то время, когда объект отображения данных автоматически гидратируется при извлечении записи, платформа отслеживает первичные ключи записи (или _id, в случае MongoDB и Jig) - поэтому она знает, какая запись должна быть обновлена ​​или удалена - даже когда значения первичных ключей изменены. Программно-гидратированный картограф данных, значения которого не были извлечены из базы данных, но заполнены приложением, не будет иметь памяти предыдущих значений в своих первичных ключах. То же самое относится к MongoDB и Jig, но с использованием объекта в _idкачестве ссылки. Итак, когда мы создали экземпляр$user объект выше и заполнил его свойства значениями из нашей программы - даже не извлекая запись из пользовательской таблицы, F3 знает, что она должна вставить эту запись.

Объект картографа не будет пустым после save(). Если вы хотите добавить новую запись в вашу базу данных, вы должны сначала обезвожить картограф: -

$user->reset();
$user->userID='cheetah';
$user->password=password_hash('unknown', PASSWORD_BCRYPT, [ 'cost' => 12 ]);
$user->save();

Повторный вызов save()без вызова reset()просто обновит запись, на которую в данный момент указывает маппер.

Предостережение для таблиц SQL

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

Чтобы удалить сопоставленную запись из нашей таблицы, вызовите erase()метод для автоматического гидрирования данных. Например:-

$user=new DB\SQL\Mapper($db,'users');
$user->load(['userID=? AND password=?','cheetah','ch1mp']);
$user->erase(); 

Синтаксис запроса Jig будет немного похожим:

$user=new DB\Jig\Mapper($db,'users');
$user->load(['@userID=? AND @password=?','cheetah','chimp']);
$user->erase(); 

И эквивалент MongoDB будет:

$user=new DB\Mongo\Mapper($db,'users');
$user->load(['userID'=>'cheetah','password'=>'chimp']);
$user->erase();

Прогноз погоды

Чтобы узнать, был ли наш гидрограф данных гидратирован или нет:

if ($user->dry())
echo 'Нет критериев соответствия записи';

А что Вне CRUD?

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

$f3->set('user',new DB\SQL\Mapper($db,'users'));
$f3->get('user')->copyFrom('POST');
$f3->get('user')->save();

Обратите внимание, что мы также можем использовать переменные без жира в качестве контейнеров для объектов отображения. copyFrom()Метод гидраты объекта сопоставителя с элементами из массива переменного рамочного, ключи массива из которых должен быть имена , идентичных свойства объекта картографа, который , в свою очередь , соответствует именам полой Пластинки в. Таким образом, когда отправляется веб-форма (при условии, что атрибут имени HTML установлен на userID), содержимое этого поля ввода передается $_POST['userID'], дублируется F3 в его POST.userIDпеременной и сохраняется в сопоставленном поле $user->userIDв базе данных. Процесс становится очень простым, если все они имеют элементы с одинаковыми именами. Согласованность ключей массива, т.е. имен токенов шаблонов, имен переменных среды и имен полей, является ключевой smile

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

$f3->set('user',new DB\SQL\Mapper($db,'users'));
$f3->get('user')->load(['userID=?','jane']);
$f3->get('user')->copyTo('POST'); 

Затем мы можем присвоить {{@ POST.userID}} атрибуту значения того же поля ввода. Подводя итог, поле ввода HTML будет выглядеть так:

save(), update(), copyFrom()Методы картографа данных и параметризованные варианты load()и erase()безопасны от инъекции SQL.

Навигация и пагинация

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

$user=new DB\SQL\Mapper($db,'users');
$user->load('visits>3');; 
// Переписать как параметризованный запрос 
$user->load(['visits>?',3]);

// Для пользователей MongoDB: - 
// $user=new DB\Mongo\Mapper($db,'users');
// $user->load(['visits'=>['$gt'=>3]]);

// Если вы предпочитаете Jig: - 
// $user=new DB\Jig\Mapper($db,'users');
// $user->load('@visits>?',3);

// Вывести userID первой записи, которая соответствует критериям 
echo $user->userID; 
// Перейти к следующей записи, которая соответствует тем же критериям 
$user->skip(); // это то же что: $user->skip(1);
// Вернуться к первой записи 
$user->skip(-1);
// Переместить три записи вперед 
$user->skip(3);

Вы можете использовать $user->next()в качестве замены $user->skip(), и $user->prev()если вы думаете, что это дает больше смысла
$user->skip(-1).

Используйте dry()метод, чтобы проверить, маневрировали ли вы за пределами набора результатов. dry()вернет TRUE, если вы попробуете skip(-1)на первой записи. Он также вернет TRUE, если вы skip(1)в последней записи, которая соответствует критериям поиска.

load()Метод принимает второй аргумент: массив вариантов , содержащих пары ключ-значение , таких как: -

$user->load(
    ['visits>?',3],
    [
        'order'=>'userID DESC'
        'offset'=>5,
        'limit'=>3
    ]
); 

Если вы используете MySQL, запрос переводится в:

SELECT * FROM users
WHERE visits>3
ORDER BY userID DESC
LIMIT 3 OFFSET 5;

Это один из способов представления данных небольшими порциями. Вот еще один способ разбить результаты на страницы:

$page=$user->paginate(2,5,['visits>?',3]);

В приведенном выше сценарии F3 будет извлекать записи, которые соответствуют критериям 'visits>3'. Затем результаты будут ограничены 5 записями (на страницу), начиная со смещения страницы 2 (на основе 0). Фреймворк вернет массив, состоящий из следующих элементов:

[subset] array of mapper objects that match the criteria
[count] number of subsets available
[pos] actual subset position

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

Виртуальные поля

Есть случаи, когда вам нужно получить вычисленное значение поля или перекрестную ссылку из другой таблицы. Введите виртуальные поля. Мини-ORM SQL позволяет вам работать с данными, полученными из существующих полей.

Предположим, у нас есть следующая таблица, определенная как:

CREATE TABLE products
    productID VARCHAR(30),
    description VARCHAR(255),
    supplierID VARCHAR(30),
    unitprice DECIMAL(10,2),
    quantity INT,
    PRIMARY KEY(productID)
); 

Нет totalpriceполя не существует, так что мы можем сказать рамки для запроса от двигателя базы данных арифметического произведение двух полей: -

$item=new DB\SQL\Mapper($db,'products');
$item->totalprice='unitprice*quantity';
$item->load(['productID=:pid',':pid'=>'apple']);
echo $item->totalprice;

Приведенный выше фрагмент кода определяет виртуальное поле с именем, totalpriceкоторое вычисляется путем умножения unitpriceна quantity. SQL mapper сохраняет это правило / формулу, поэтому, когда придет время извлечь запись из базы данных, мы можем использовать виртуальное поле как обычное сопоставленное поле.

Вы можете иметь более сложные виртуальные поля: -

$item->mostNumber='MAX(quantity)';
$item->load();
echo $item->mostNumber; 

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

Вы также можете получить значение из другой таблицы:

$item->supplierName=
    'SELECT name FROM suppliers '.
    'WHERE products.supplierID=suppliers.supplierID';
$item->load();
echo $item->supplierName; 

Каждый раз, когда вы загружаете запись из таблицы продуктов, ORM делает перекрестные ссылки supplerIDв productsтаблице с таблицей supplierIDв suppliersтаблице.

Чтобы уничтожить виртуальное поле, используйте unset($item->totalPrice); ,isset($item->totalPrice)Выражение возвращает значение TRUE , если totalPriceвиртуальное поле было определено, или FALSE , если в противном случае.

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

Кто ищет, тот найдет

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

$frequentUsers=$user->find(['visits>?',3],['order'=>'userID']);

Синтаксис запроса Jig Mapper имеет небольшое сходство:

$frequentUsers=$user->find(['@visits>?',3],['order'=>'userID']);

Эквивалентный код с использованием преобразователя MongoDB: -

$frequentUsers=$user->find(['visits'=>['$gt'=>3]],['userID'=>1]);

find()Метод ищет в usersтаблице записей , которые соответствуют критериям, сортирует результат, userIDи возвращает результат в виде массива объектов Mapper. find('visits>3')отличается от load('visits>3'). Последний относится к текущему $userобъекту. find()не имеет никакого влияния на skip().

Важное замечание : Объявление пустого условия, NULL или строки нулевой длины в качестве первого аргумента find()или load()приведет к получению всех записей. Убедитесь, что вы знаете, что делаете - возможно, вы превысите PHP memory_limit для больших таблиц или коллекций.

find()Метод имеет следующий синтаксис: -

find(
    $criteria,
    [
        'group'=>'foo',
        'order'=>'foo,bar',
        'limit'=>5,
        'offset'=>0
    ]
);

find () возвращает массив объектов. Каждый объект является сопоставителем записи, которая соответствует заданным критериям.

$place=new DB\SQL\Mapper($db,'places');
$list=$place->find('state="New York"');
foreach ($list as $obj)
    echo $obj->city.', '.$obj->country;

Если вам нужно преобразовать объект сопоставления в ассоциативный массив, используйте cast()метод: -

$array=$place->cast();
echo $array['city'].', '.$array['country'];

Чтобы получить количество записей в таблице, которые соответствуют определенному условию, используйте count()метод.

if (!$user->count(['visits>?',10]))
echo 'We need a better ad campaign!';

Есть также select()метод, который похож на, find()но обеспечивает более детальный контроль над возвращаемыми полями. Он имеет SQL-подобный синтаксис:

select(
    'foo, bar, MIN(baz) AS lowest',
    'foo > ?',
    [
        'group'=>'foo, bar',
        'order'=>'baz ASC',
        'limit'=>5,
        'offset'=>3
    ]
);

Как и find()метод, select()не изменяет содержимое объекта mapper. Это только удобный метод для запроса сопоставленной таблицы. Возвращаемым значением обоих методов является массив объектов Mapper. Использование dry()для определения того, была ли запись найдена одним из этих методов, неуместно. Если ни одна запись не соответствует критерию find()или select(), возвращаемое значение является пустым массивом.

Профилирование

Если вы когда-нибудь захотите выяснить, какие операторы SQL, созданные непосредственно вашим приложением (или косвенно через объекты mapper), вызывают узкие места в производительности, вы можете сделать это с помощью простого: -

echo $db->log();

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

Иногда этого не достаточно

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

class Vendor extends DB\SQL\Mapper {

    // Instantiate mapper
    function __construct(DB\SQL $db) {
        // This is where the mapper and DB structure synchronization occurs
        parent::__construct($db,'vendors');
    }

    // Specialized query
    function listByCity() {
        return $this->select(
            'vendorID,name,city',['order'=>'city DESC']);
        /*
            We could have done the the same thing with plain vanilla SQL:-
            return $this->db->exec(
                'SELECT vendorID,name,city FROM vendors '.
                'ORDER BY city DESC;'
            );
        */
    }

}

$vendor=new Vendor;
$vendor->listByCity();

Расширение картографических данных таким способом является простым способом построения моделей, связанных с БД вашего приложения.

Плюсы и минусы

Если вы разбираетесь в SQL, вы, вероятно, скажете: все в ORM может быть обработано с помощью SQL-запросов старой школы. В самом деле.Мы можем обойтись без дополнительных прослушивателей событий, используя триггеры базы данных и хранимые процедуры. Мы можем выполнять реляционные запросы с объединенными таблицами. ORM просто ненужные накладные расходы. Но дело в том, что картографы данных предоставляют вам дополнительную функциональность использования объектов для представления объектов базы данных. Как разработчик, вы можете писать код быстрее и быть более продуктивным. Полученная программа будет чище, если не короче. Но вам придется взвесить преимущества против компромисса в скорости - особенно при работе с большими и сложными хранилищами данных. Помните, что все ORMS - независимо от их толщины - всегда будут просто еще одним уровнем абстракции. Им по-прежнему приходится передавать работу базовым движкам SQL.

По своему дизайну ORM в F3 не предоставляют методов для прямого соединения объектов друг с другом, то есть объединения SQL - потому что это открывает червя. Это делает ваше приложение более сложным, чем должно быть, и существует тенденция блокировать объекты с помощью техник активных или ленивых выборок и даже не синхронизироваться из-за наследования объектов и полиморфизма (несоответствия импеданса) с объектами базы данных, с которыми они сопоставлены , Существуют косвенные способы сделать это в маппере SQL, используя виртуальные поля, но вам придется делать это программно и на свой страх и риск.

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

Прежде чем объединить несколько объектов в приложении для управления базовыми таблицами в вашей базе данных, подумайте об этом: создание представлений для представления отношений и триггеров для определения поведения объектов в ядре базы данных более эффективны. Механизмы реляционных баз данных предназначены для обработки представлений, объединенных таблиц и триггеров. Они не тупые хранилища данных. Таблицы, объединенные в представление, будут отображаться как одна таблица, и Fat-Free может автоматически отображать представление так же, как и обычную таблицу. Репликация JOINs как реляционных объектов в PHP медленнее, чем машинный код, реляционная алгебра и логика оптимизации движка базы данных. Кроме того, многократное объединение таблиц в нашем приложении является верным признаком того, что дизайн базы данных должен подвергаться аудиту, а представления считаются неотъемлемой частью поиска данных.Если таблица часто ссылается на данные из другой таблицы, рассмотрите возможность нормализации своих структур или создания представления. Затем создайте объект сопоставления для автоматического сопоставления этого вида. Это быстрее и требует меньше усилий.

Рассмотрим это представление SQL, созданное внутри вашей базы данных:

CREATE VIEW combined AS
    SELECT
        projects.project_id AS project,
        users.name AS name
    FROM projects
    LEFT OUTER JOIN users ON
        projects.project_id=users.project_id AND
        projects.user_id=users.user_id;

Код вашего приложения становится простым, поскольку ему не нужно поддерживать два объекта mapper (один для таблицы проектов, а другой для пользователей) только для извлечения данных из двух объединенных таблиц: -

$combined=new DB\SQL\Mapper($db,'combined');
$combined->load(['project=?',123]);
echo $combined->name;

Совет: используйте инструменты так, как они предназначены. Fat-Free уже имеет простой в использовании помощник SQL. Используйте его, если вам нужен больший молот smile Постарайтесь найти баланс между удобством и производительностью. SQL всегда будет вашим запасным вариантом, если вы работаете со сложными и устаревшими структурами данных.

Плагины Plug-Ins

О плагинах F3.

Плагины - это не что иное, как классы с автозагрузкой, которые используют встроенные фреймворки для расширения возможностей и функциональности F3. Если вы хотите внести свой вклад, оставьте заметку в Обсуждаемой области без жира, размещенной в группах Google, или сообщите нам об этом на #fatfreeIRC-канале FreeNode . Кто-то еще может быть вовлечен в подобный проект. Сообщество фреймворка будет очень признательно, если мы объединим наши усилия
CAPTCHA Изображения

Могут быть случаи, когда вы хотите сделать свои формы более защищенными от спам-ботов и вредоносных автоматических сценариев. F3 предоставляет captcha()метод для генерации изображений со случайным текстом, которые предназначены для распознавания только людьми.

$img = new Image();
$img->captcha('fonts/CoolFont.ttf',16,5,'SESSION.captcha_code');
$img->render(); 

В этом примере генерируется случайное изображение на основе желаемого шрифта TrueType. fonts/Папка является вложенной в приложении UIпути. Второй параметр указывает размер шрифта, а третий аргумент определяет количество генерируемых шестнадцатеричных символов.

Последний аргумент представляет имя переменной F3. Здесь F3 будет хранить строковый эквивалент изображения CAPTCHA. Чтобы сделать строку безопасной для перезагрузки, мы указали переменную сеанса: - SESSION.captcha_codeкоторая сопоставляется $_SESSION['captcha_code'], которую вы можете использовать позже, чтобы проверить, соответствует ли элемент ввода в представленной форме этой строке.
Получение данных с другого сайта

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

$web=new Web;
$request=$web->request('http://www.google.com/');
// another way to do it:-
$request=Web::instance()->request('http://www.google.com/');

Этот простой пример отправляет HTTP-запрос на страницу, расположенную по адресу www.google.com, и сохраняет его в $requestпеременной PHP. request()Метод возвращает массив , содержащий ответ HTTP таким образом, что $request['headers']и $request['body']представляют заголовки ответа и тело, соответственно. Мы могли бы сохранить содержимое с помощью команды F3 :: set или вывести вывод непосредственно в наш браузер. Получение другой HTML-страницы в сети может не иметь никакой практической цели. Но это может быть особенно полезно в приложениях ReSTful, таких как запросы к серверу CouchDB.

$host='localhost:5984';
$web->request($host.'/_all_dbs'),
$web->request($host.'/testdb/',['method'=>'PUT']);

Возможно, вы заметили, что вы можете передать массив дополнительных опций в request()метод:

$web->request(
    'https://www.example.com:443?'.
    http_build_query(
        [
            'key1'=>'value1',
            'key2'=>'value2'
        ]
    ),
    [
        'headers'=>[
            'Accept: text/html,application/xhtml+xml,application/xml',
            'Accept-Language: en-us'
        ],
        'follow_location'=>FALSE,
        'max_redirects'=>30,
        'ignore_errors'=>TRUE
    ]
);

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

Fat-Free будет использовать любые доступные на вашем веб-сервере средства для request()запуска метода: PHP stream wrappers ( allow_url_fopen), модуль cURL или низкоуровневые сокеты.

Обработка загрузок файлов

В F3 есть утилита для отправки файлов HTTP-клиенту, то есть для выполнения запросов на загрузку. Вы можете использовать его, чтобы скрыть реальный путь к загружаемым файлам. Это добавляет некоторый уровень безопасности, потому что пользователи не смогут загружать файлы, если они не знают имен файлов и их местоположения. Вот как это делается:

$f3->route('GET /downloads/@filename',
    function($f3,$args) {
        // send() method returns FALSE if file doesn't exist
        if (!Web::instance()->send('/real/path/'.$args['filename']))
            // Generate an HTTP 404
        $f3->error(404);
    }
);

Удаленные и распределенные приложения

Этот request()метод также можно использовать в сложных приложениях SOAP или XML-RPC, если вы обнаружите необходимость в другом веб-сервере для обработки данных от имени вашего компьютера, что позволит использовать возможности распределенных вычислений. W3Schools.com имеет отличное руководство по SOAP. С другой стороны, TutorialsPoint.com дает хороший обзор XML-RPC.

Оптимизация


Cache Engine

Кэширование статических веб-страниц - таким образом, код в некоторых обработчиках маршрута может быть пропущен, а шаблоны не должны обрабатываться повторно - это один из способов снизить нагрузку на ваш веб-сервер, чтобы он мог сосредоточиться на других задачах. Вы можете активировать механизм кэширования фреймворка, предоставив $f3->route()методу третий аргумент . Просто укажите количество секунд до истечения срока действия кэшированной веб-страницы: -

$f3->route('GET /my_page','App->method',60);

Вот как это работает. В этом примере, когда F3 обнаруживает, что URL /my_pageпроисходит доступ в первый раз, он выполняет обработчик маршрута, представленный вторым аргументом, и сохраняет все выходные данные браузера во встроенный кэш фреймворка (на стороне сервера). Аналогичная инструкция автоматически отправляется в веб-браузер пользователя (на стороне клиента), поэтому вместо отправки идентичного запроса на сервер в течение 60-секундного периода браузер может просто получить страницу локально. Фреймворк использует кеш для совершенно другой цели - предоставление кэшированных фреймворком данных другим пользователям, запрашивающим ту же веб-страницу в течение 60-секундного периода времени. Он пропускает выполнение обработчика маршрута и обслуживает ранее сохраненную страницу непосредственно с диска. Когда кто-то пытается получить доступ к тому же URL-адресу после истечения 60-секундного таймера, F3 обновит кэш новой копией.

Веб-страницы со статическими данными являются наиболее вероятными кандидатами для кэширования. Fat-Free не будет кэшировать веб-страницу по указанному URL, если третий аргумент в $f3->route()методе равен нулю или не указан . F3 соответствует спецификациям HTTP: кешируются только запросы GET и HEAD.

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

Например, вы проектировали свой сайт таким образом , что все веб - страницы имеют опции меню: "Home", "About Us"и "Login", отображается , когда пользователь не вошел в ваше приложение. Вы также хотите , пункты меню , чтобы изменить: "Home", "About Us"и "Logout"., Как только пользователь вошел в системе Если вы проинструктированы Обезжиренным кэшировать содержимое "About Us"страницы (которая включает в себя опцию меню), он делает это , а также передает ту же самую инструкцию к клиенту HTTP. Независимо от состояния сеанса пользователя, т. Е. Вошел в систему или вышел из системы, браузер пользователя сделает снимок страницы в состоянии сеанса, в котором он находился. Будущие запросы пользователя на"About Us"На странице до истечения времени ожидания кэша отобразятся те же пункты меню, которые были доступны в то время, когда страница была первоначально сохранена. Теперь пользователь, возможно, уже вошел в систему, но пункты меню остаются такими же, как если бы такого события не происходило. Это не то поведение, которое мы хотим от нашего приложения.

Некоторые указатели: -

Не кэшируйте динамические страницы. Совершенно очевидно, что вы не хотите кэшировать данные, которые часто изменяются. Однако вы можете активировать кэширование на страницах, которые содержат данные, обновляемые ежечасно, ежедневно или даже раз в год. В целях безопасности платформа ограничивает использование механизма кэширования только HTTP- GETмаршрутами. Он не будет кешировать отправленные формы! Не активируйте кеш на веб-страницах, которые на первый взгляд выглядят статичными. В нашем примере контент «О нас» может быть статичным, а меню - нет.

Активируйте кеширование на страницах, которые доступны только в ОДНОМ состоянии сеанса. Если вы хотите кэшировать "About Us"страницу, убедитесь, что она доступна только тогда, когда пользователь не вошел в систему.
Если у вас есть RAMdisk или быстрый твердотельный накопитель, настройте CACHEглобальную переменную так, чтобы она указывала на этот накопитель. Это заставит ваше приложение работать как гоночная машина Формулы 1.

Примечание. Не устанавливайте значение тайм-аута на очень длительный период, пока вы не будете готовы развернуть свое приложение, то есть состояние выпуска или производства. Изменения, которые вы вносите в любой из ваших PHP-скриптов, могут не оказать ожидаемого влияния на отображаемый вывод, если страница существует в кэше фреймворка, а срок действия не истек. Если вы изменяете программу, которая генерирует страницу, на которую воздействует таймер кэша, и хотите, чтобы эти изменения вступили в силу немедленно, вы должны очистить кэш, удалив файлы в каталоге cache / (или любом другом пути, на который CACHEуказывает глобальная переменная). F3 автоматически обновит кеш при необходимости. На стороне клиента вы мало что можете сделать, кроме как проинструктировать пользователя очистить кеш браузера или подождать, пока закончится период кеша.

PHP должен быть правильно настроен для правильной работы механизма кэширования F3. Часовой пояс вашей операционной системы должен быть синхронизирован с настройкой date.timezone в php.iniфайле.

Подобно маршрутам, Fat-Free также позволяет кэшировать запросы к базе данных. Увеличение скорости может быть весьма значительным, особенно при использовании сложных операторов SQL, которые включают поиск статических данных или содержимого базы данных, которое редко изменяется. Активировать кэш запросов к базе данных, чтобы платформе не приходилось каждый раз повторять операторы SQL, так же просто, как добавить третий аргумент в команду F3 :: sql - тайм-аут кэша. Например:-

$db->exec('SELECT * from sizes;',NULL,86400)

Если мы ожидаем , что результат этого запроса к базе данных , чтобы всегда быть Small, Mediumи в Largeтечение 24-часового периода, мы задаем 86400секунды , как 2 - й аргумент так Обезжиренные не должен выполнить запрос более одного раза в день. Вместо этого платформа будет сохранять результат в кеше, извлекать его из кеша каждый раз, когда поступает запрос в течение указанного 24-часового периода времени, и повторно выполнять запрос по истечении таймера.

Средство отображения данных SQL также использует механизм кэширования для оптимизации синхронизации структур таблиц с объектами, которые их представляют. По умолчанию это 60секунды. Если вы внесете какие-либо изменения в структуру таблицы в вашем ядре базы данных, вам придется подождать, пока истечет таймер кэша, прежде чем вы увидите эффект в вашем приложении. Вы можете изменить это поведение, указав третий аргумент для конструктора картографических данных. Установите для него высокое значение, если вы не собираетесь вносить какие-либо дальнейшие изменения в структуру таблицы.

$user=new DB\SQL\Mapper($db,'users',86400);

По умолчанию механизм кэширования Fat-Free отключен. Вы можете включить его и разрешить автоопределение APC, WinCache или XCache. Если он не может найти подходящий бэкэнд, F3 будет использовать файловую систему, то есть tmp/cache/папку: -

$f3->set('CACHE',TRUE);

Отключить кеш так же просто, как:

$f3->set('CACHE',FALSE);

Если вы хотите переопределить функцию автоопределения, вы можете сделать это - как в случае с серверной частью Memcached, которую F3 также поддерживает: -

$f3->set('CACHE','memcache=localhost:11211');

Вы также можете использовать механизм кэширования для хранения собственных переменных. Эти переменные сохраняются между HTTP-запросами и остаются в кэше, пока механизм не получит инструкции по их удалению. Чтобы сохранить значение в кеше: -

$f3->set('var','I want this value saved',90);

$f3->set()Третий аргумент метода указывает платформе на сохранение переменной в кэше в течение 90 секунд. Если ваше приложение выдает в $f3->get('var')течение этого периода, F3 автоматически получит значение из кэша. Аналогичным образом $f3->clear('var')удалит значение из кеша и оперативной памяти. Если вы хотите определить, существует ли переменная в кеше, `$ f3-> exist ('var')); возвращает одно из двух возможных значений: FALSE, если переданная переменная структуры не существует в кэше, или целое число, представляющее время, в которое переменная была сохранена (Un * x время в секундах, с точностью до микросекунды).
Соблюдение Javascript и CSS на здоровой диете

Fat-Free также имеет Javascript и CSS-компрессор, доступный в веб-плагине. Он может объединить все ваши CSS-файлы в одну таблицу стилей (или Javascript-файлы в один скрипт), чтобы уменьшить количество компонентов на веб-странице. Сокращение количества HTTP-запросов к вашему веб-серверу приводит к более быстрой загрузке страницы. Сначала вам нужно подготовить свой HTML-шаблон, чтобы он мог воспользоваться этой функцией. Что-то вроде:-


Сделайте то же самое со своими файлами Javascript: -

 

Конечно, нам нужно настроить маршрут, чтобы ваше приложение могло обрабатывать необходимый вызов компрессора CSS / Javascript без жира: -

$f3->route('GET /minify/@type',
    function($f3,$args) {
        $f3->set('UI',$args['type'].'/');
        echo Web::instance()->minify($_GET['files']);
    },
    3600
);

И это все, что нужно сделать! minify()читает каждый файл ( typo.cssи grid.cssв нашем примере CSS, underscore.jsв нашем примере Javascript), удаляет все ненужные пробелы и комментарии, объединяет все связанные элементы в единый компонент веб-страницы и прикрепляет дату истечения в далеком будущем, чтобы веб-браузер пользователя может кэшировать данные. Важно, чтобы PARAMS.typeбазовая переменная указывала на правильный путь. В противном случае механизм перезаписи URL внутри компрессора не найдет файлы CSS / Javascript.

Кэширование на стороне клиента

В наших примерах фреймворк отправляет дату истечения в далеком будущем веб-браузеру клиента, поэтому любой запрос на тот же блок CSS или Javascript будет поступать с жесткого диска пользователя. На стороне сервера F3 будет проверять каждый запрос и видеть, были ли уже кэшированы блоки CSS или Javascript. Указанный нами маршрут имеет период обновления кеша в 3600секундах. Кроме того, если веб-браузер отправляет If-Modified-Sinceзаголовок запроса и инфраструктура обнаруживает, что кэш не изменился, F3 просто отправляет HTTP 304 Not Modifiedответ, поэтому контент фактически не доставляется. Без If-Modified-Sinceзаголовка Fat-Free отображает вывод из кэшированного файла, если он доступен. В противном случае соответствующий код выполняется.

Совет: Если вы не часто изменяете свои файлы Javascript / CSS (как это было бы, если вы используете библиотеку Javascript, такую ​​как jQuery, MooTools, Dojo и т. Д.), Рассмотрите возможность добавления таймера кэша к маршруту, ведущему к вашему Javascript. / CSS минимизировать обработчик (3-й аргумент F3 :: route ()), поэтому Fat-Free не сжимает и объединяет эти файлы каждый раз, когда такой запрос получен.

Ускорение кода PHP

Хотите, чтобы ваш сайт работал еще быстрее? Fat-Free лучше всего работает с альтернативным PHP Cache (APC), XCache или WinCache. Эти расширения PHP повышают производительность вашего приложения за счет оптимизации ваших PHP-скриптов (включая фреймворк-код).

Регулирование пропускной способности

Быстрое приложение, которое обрабатывает все HTTP-запросы и отвечает на них в кратчайшие сроки, не всегда является хорошей идеей, особенно если ваша пропускная способность ограничена или трафик на вашем веб-сайте особенно велик. Страницы обслуживания как можно скорее также делают ваше приложение уязвимым для атак типа «отказ в обслуживании» (DOS). F3 имеет функцию регулирования полосы пропускания, которая позволяет вам контролировать скорость обслуживания ваших веб-страниц. Вы можете указать, сколько времени потребуется для обработки запроса: -

$f3->route('/throttledpage','MyApp->handler',0,128);

В этом примере инфраструктура будет обслуживать веб-страницу со скоростью 128 КБ / с.

Регулирование пропускной способности на уровне приложений может быть особенно полезным для страниц входа в систему. Медленное реагирование на атаки по словарю - хороший способ снизить риск подобного рода.

Модульное тестирование

Пуленепробиваемый код.

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

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

F3 облегчает отладку программ, не мешая вашим обычным мыслительным процессам. Среда не требует, чтобы вы строили сложные классы ООП, тяжелые тестовые структуры и навязчивые процедуры.

Единица (или тестовое устройство) может быть функцией / методом или классом. Давайте рассмотрим простой пример:

function hello() {
    return 'Hello, World';
} 

Сохраните его в файле с именем hello.php. Теперь, как мы узнаем, что это действительно работает как ожидалось? Давайте создадим нашу процедуру испытаний: -

$f3 = require('lib/base.php');

// Установить 
$test=new Test;
include('hello.php');

// Здесь начинаются тесты 
$test->expect(
    is_callable('hello'),
    'hello() is a function'
);

// Еще один тест 
$hello=hello();
$test->expect(
    !empty($hello),
    'Something was returned'
);

// Этот тест должен пройти успешно 
$test->expect
    is_string($hello),
    'Return value is a string'
);

// Этот тест обязательно завершится с ошибкой 
$test->expect(
    strlen($hello)==13,
    'String length is 13'
);

// Показать результаты; не MVC, но давайте оставим это простым 
foreach ($test->results() as $result) {
    echo $result['text'].'
'; if ($result['status']) echo 'Pass'; else echo 'Fail ('.$result['source'].')'; echo '
'; }

Сохраните его в файле с именем test.php. Таким образом, мы можем сохранить целостность hello.php.

Теперь вот основа нашего модульного тестирования.

Встроенный Testкласс F3 отслеживает результат каждого expect()вызова. Выходные данные $test->results()- это массив массивов с ключами text(аргумент зеркального отображения 2 of expect()), status(логическое значение, представляющее результат теста) и source(имя файла / номер строки конкретного теста) для помощи в отладке.

Fat-Free дает вам возможность отображать результаты тестов любым удобным для вас способом. Вы можете получить вывод в виде простого текста или даже симпатичного шаблона HTML. Итак, как нам запустить наш модульный тест? Если вы сохранили test.phpв корневой папке документа, вы можете просто открыть браузер и указать адрес http://localhost/test.php. Это все, что нужно сделать.

Поддельные HTTP-запросы

F3 дает вам возможность имитировать HTTP-запросы из вашей PHP-программы, чтобы вы могли протестировать поведение определенного маршрута. Вот простая ложная просьба:

$f3->mock('GET /test?foo=bar');

Чтобы смоделировать запрос POST и отправить смоделированную форму HTML: -

$f3->mock('POST /test',['foo'=>'bar']);

В ожидании худшего, что может случиться

После того, как вы освоите тестирование самых маленьких модулей вашего приложения, вы можете перейти к более крупным компонентам, модулям и подсистемам - проверяя, правильно ли части взаимодействуют друг с другом. Тестирование управляемых фрагментов кода приводит к созданию более надежных программ, которые работают так, как вы ожидаете, и вплетает процесс тестирования в структуру вашего цикла разработки. Вопрос, который нужно задать себе: - Я проверил все возможные сценарии? Чаще всего те ситуации, которые не были приняты во внимание, являются вероятными причинами ошибок. Модульное тестирование очень помогает в минимизации этих случаев. Даже несколько тестов на каждом приборе могут значительно уменьшить головную боль. С другой стороны, написание приложений без юнит-тестирования вообще создает проблемы.

Краткий справочник

Системные переменные:

string AGENT

Автоопределенный пользовательский агент HTTP, например Mozilla/5.0 (Linux; Android 4.2.2; Nexus 7) AppleWebKit/537.31.

bool AJAX

TRUEесли обнаружен запрос XML HTTP, в FALSEпротивном случае.

string AUTOLOAD

Путь поиска для определенных пользователем классов PHP, которые фреймворк попытается автоматически загрузить во время выполнения. Принимает pipe ( |), запятую ( ,) или точку с запятой ( 😉 в качестве разделителя пути.

string BASE

Путь к index.phpглавному / переднему контроллеру.

string BODY

тело HTTP-запроса для постобработки ReSTful.

bool/string CACHE

Бэкэнд кеша. Если не присвоено значение типа 'memcache=localhost'(и присутствует модуль PHP memcache), F3 автоматически обнаруживает присутствие APC, WinCache и XCache и использует первый доступный модуль PHP, если установлено значение TRUE. Если ни один из этих модулей PHP не доступен, используется серверная часть на основе файловой системы (каталог по умолчаниюsmile tmp/cache. Каркас отключает механизм кэширования, если ему присвоено FALSEзначение.

bool CASELESS

Сопоставление шаблонов маршрутов с входящими URI по умолчанию не учитывает регистр. Установите, чтобы FALSEсделать его чувствительным к регистру.

array COOKIE, GET, POST, REQUEST, SESSION, FILES, SERVER, ENV

Фреймворк-эквиваленты PHP-глобалов. Переменные могут использоваться во всем приложении. Однако прямое использование в шаблонах не рекомендуется из-за угроз безопасности.

integer DEBUG

Стек трассировки многословия. Назначьте значения от 1 до 3 для увеличения уровней многословия. Ноль (0) подавляет трассировку стека. Это значение по умолчанию, и оно должно быть назначенным параметром на рабочем сервере.

string DNSBL

Разделенный запятыми список серверов черного списка DNS . Framework генерирует 403 Forbiddenошибку, если IPv4-адрес пользователя указан на указанных серверах.

array DIACRITICS

Пары ключ-значение для перевода символов из внешнего в ASCII.

string ENCODING

Набор символов, используемый для кодирования документов. Значение по умолчанию UTF-8.

array ERROR

Информация о последней произошедшей HTTP-ошибке. ERROR.codeэто код состояния HTTP. ERROR.statusсодержит краткое описание ошибки. ERROR.textпредоставляет более подробную информацию. Для ошибок HTTP 500 используйте ERROR.traceдля получения трассировки стека.

bool ESCAPE

Используется для включения / отключения авто-экранирования.

string EXEMPT

Разделенный запятыми список адресов IPv4, исключенных из поиска DNSBL.

string FALLBACK

Язык (и словарь) для использования, если нет перевода.

bool HALT

Если TRUE (по умолчанию), каркас останавливается после обнаружения нефатальной ошибки.

array HEADERS

Заголовки HTTP-запроса, полученные сервером.

bool HIGHLIGHT

Включить / отключить подсветку синтаксиса трассировки стека. Значение по умолчанию: TRUE(требуется code.cssтаблица стилей).

string HOST

Имя хоста сервера. Если $_SERVER['SERVER_NAME']недоступно, используется возвращаемое значение gethostname().

string IP

Удаленный IP-адрес. Платформа извлекает адрес из заголовков, если HTTP-клиент находится за прокси-сервером.

array JAR

Параметры cookie по умолчанию.

string LANGUAGE

Текущий активный язык. Значение используется для загрузки соответствующего файла языкового перевода в папку, на которую указывает LOCALES. Если установлено значение NULL, язык определяется автоматически из Accept-Languageзаголовка HTTP- запроса.

string LOCALES

Расположение языковых словарей.

string LOGS

Расположение пользовательских логов.

mixed ONERROR

Функция обратного вызова для использования в качестве пользовательского обработчика ошибок.

string PACKAGE

Название фреймворка.

array PARAMS

Захваченные значения токенов, определенные в route()шаблоне. PARAMS.0содержит захваченный URL относительно веб-корня.

string PATTERN

Содержит шаблон маршрутизации, соответствующий текущему URI запроса.

string PLUGINS

Расположение плагинов F3. Значением по умолчанию является папка, в которой находится код платформы, т.е. путь к base.php.

int PORT

Порт прослушивания TCP / IP, используемый веб-сервером.

string PREFIX

Строка перед термином словарь языка.

bool QUIET

Тумблер для подавления или включения стандартных выходных сообщений и сообщений об ошибках. Особенно полезно при юнит-тестировании.

bool RAW

Отключить автоматическое хранение тела HTTP-запроса в BODY. Должно быть ИСТИНА при обработке больших данных, поступающих с php://inputкоторых не помещается в памяти. Значение по умолчанию:FALSE

string REALM

Полный канонический URL.

string RESPONSE

Тело последнего HTTP-ответа. F3 заполняет эту переменную независимо от QUIETнастройки.

string ROOT

Абсолютный путь к корневой папке документа.

array ROUTES

Содержит определенные маршруты приложений.

string SCHEME

Протокол сервера, т . Е. httpИли https.

string SERIALIZER

Стандартный сериализатор. Обычно устанавливается на php, если igbinaryрасширение PHP не определяется автоматически. Назначьте jsonпри желании.

string TEMP

Временная папка для кеша, блокировки файловой системы, скомпилированные шаблоны F3 и т. Д. По умолчанию это tmp/папка внутри корня сети. Отрегулируйте в соответствии с политикой безопасности вашего сайта.

string TZ

Часовой пояс по умолчанию. Изменение этого значения автоматически вызывает базовую date_default_timezone_set()функцию.

string UI

Путь поиска файлов пользовательского интерфейса, используемых методом Viewи Templateклассов render(). Значением по умолчанию является веб-корень. Принимает pipe ( |), запятую ( ,) или точку с запятой ( 😉 в качестве разделителя для нескольких путей.

callback UNLOAD

Выполняется фреймворком при выключении скрипта.

string UPLOADS

Каталог, в котором сохранены загрузки файлов.

string URI

URI текущего HTTP-запроса.

string VERB

Текущий метод HTTP-запроса.

string VERSION

Каркасная версия.

Шаблонные директивы

@token

Заменить @token на значение эквивалентной переменной F3.

{{ mixed expr }}

Оценка. exprможет включать в себя токены шаблонов, константы, операторы (унарные, арифметические, троичные и реляционные), круглые скобки, преобразователи типов данных и функции. Если не атрибут директивы шаблона, выводится результат.

{{ string expr | raw }}

Рендеринг без спасения expr. F3 автоматически экранирует строки по умолчанию.

{{ string expr | esc }}

Рендер сбежал expr. Это поведение фреймворка по умолчанию. | esc | escСуффикс необходим, только если для ESCAPEглобальной переменной задано значение FALSE.

{{ string expr, arg1, ..., argN | format }}

Визуализация ОИТ формат exprи передать запятую аргументов, где arg1, ..., argnэто одно из: - 'date', 'time', 'number, integer', 'number, currency', или 'number, percent'.

Получить содержимое subtemplateи вставить в текущую позицию в шаблоне, если необязательное условие TRUE.

text-block

Удалить text-blockво время выполнения. Используется для встраивания комментариев в шаблоны.

text-block

Отображать text-blockкак есть, без интерпретации / модификации с помощью механизма шаблонов.


    true-block
    false-block
 

Оцените состояние. Если TRUE, то true-blockотображается. В противном случае false-blockиспользуется.


    text-block
 

Оцените fromзаявление один раз. Проверьте, является ли выражение в toатрибуте TRUE, визуализируйте text-blockи оцените stepоператор. Повторите итерацию, пока toвыражение не будет FALSE.


    text-block
 

Повторите text-blockстолько раз, сколько есть элементов в переменной массива @groupили выражении expr. @keyи @valueфункционировать так же, как пара ключ-значение в эквивалентном foreach()операторе PHP . Переменная, представленная keyв counterатрибуте, увеличивается на 1каждую итерацию.


    
        text-block
    
    .
    .
    .

Эквивалент структуры таблицы переходов в случае переключения PHP.

{* text-block *}

Псевдоним для .

Документация по API

Самая актуальная документация находится по адресу http://fatfreeframework.com/ . Он содержит примеры использования различных компонентов инфраструктуры.

Поддержка и лицензирование

Техническая поддержка доступна на официальном форуме обсуждения:

https://groups.google.com/forum/#!forum/f3-framework. Если вам нужна поддержка в режиме реального времени, вы можете поговорить с командой разработчиков и другими членами сообщества F3 через IRC. Мы на канале FreeNode #fatfree( chat.freenode.net). Посетите, http://webchat.freenode.net/чтобы присоединиться к разговору. Вы также можете загрузить дополнение Firefox Chatzilla или Pidgin, если у вас нет IRC-клиента, поэтому вы можете участвовать в живом чате.

Ночные сборки

F3 использует Git для контроля версий. Чтобы клонировать репозиторий кода на GitHub: -

git clone git://github.com/bcosca/fatfree.git

Если все, что вы хотите, это zipball, захватите его здесь .

Чтобы отправить отчет об ошибке, посетите https://github.com/bcosca/fatfree/issues.

Честное лицензирование

Fat-Free Framework является бесплатной и выпускается в виде программного обеспечения с открытым исходным кодом, на которое распространяются условия GNU Public License (GPL v3). Вы не можете использовать программное обеспечение, документацию и образцы, кроме как в соответствии с лицензией. Если положения и условия этой лицензии слишком ограничены для вашего использования, альтернативное лицензирование доступно за очень разумную плату.

Если вы чувствуете, что это программное обеспечение является отличным оружием в вашем программном арсенале, оно экономит вам много времени и денег, используйте его для коммерческой выгоды или в вашей организации бизнеса, пожалуйста, рассмотрите возможность сделать пожертвование для проекта. Значительное количество времени, усилий и денег было потрачено на этот проект. Ваши пожертвования помогают поддерживать этот проект и мотивировать команду разработчиков. Доноры и спонсоры получают приоритетную поддержку (24-часовое время ответа в рабочие дни).
кредиты

Fat-Free Framework - это программное обеспечение для сообщества. Это не может быть тем, что есть сегодня без помощи и поддержки со стороны следующих людей и организаций:

GitHub
Stehlik & Company
bodalgo.com
Квадратные Линии, ООО
Mirosystems
Талис Групп, ООО
Tecnilógica
Г Холдингс, ООО
С2 Девелопмент, ООО
Магазин машины
PHP Experts, Inc.
Meins und Vogel GmbH
Предоплаченные онлайн-услуги
Скромный фотограф
Кристиан Кнут
Флоран Расинё
Саша ом
Ларс Бренди Дженсен
Эйдун Ламхауге
Джермейн Мэри
Сергей Зарецкий
Даниэль Клок
Брайан Нельсон
Робертс Лапинс
Борис Гуревич
Хосе Мария Гарридо Диас
Рассвет Комфорт
Йохан Виберг
Повилас Мустейкис
Эндрю Снук
Джафар Амджад
Тейлор Макколл
Раймонд Киркланд
Юрий Герасименко
Уильям Стам
Сэм Джордж
Стив Васиура
Андреас Юнггрен
Сашанк Тадепалли
Чад епископ
Брэдли Славик
Ли Блю
Александр Шатило
Джастин Ноэль
Иван Ковач
Интернет-решения Тони
Чарльз Стиглер
Аттила ван дер Вельде
Indoblo Commerce Ltd.
Йенс Нимейер
Рагу Веер Дендукури
NovelLead BV
Эмир Алп
Доминик Шварц
Свен Заренд
LucidStorm
Nevatech
Мэтт Вильгос
Максимилиан Самме
Каспар Фрей
FocusHeart
Филип Лоуренс
Питер Бевервик
Джудит Грасс
Рэндал Хинц
Франц Йозеф
Бисваджит Наяк
Р Мохан
Майкл Месснер
Джейсон Борсет
Дмитрий Чернов
Марек Томан
Симона Кокианчич
Алан Холдинг
Филипп Хирш
Орелиен Ботерманс
Кристиан Трептов
Кубарев Дмитрий (Дмитрий Кубарев)
Александру Каталин Трандафир
Ли Харрисон
Дмитриев Иван (Иван Дмитриев)
IT_GAP
Сергеев Андрей
Стивен Дж. Миксон
Роланд Фат
Джастин Паркер
Костас Менико
Матье-Филипп Буржуа
Райан Маккиллоп
Крис Кларк
Нган Тинг Он
Эли Аргон
Серегин Андрей
Марек Томан
Diji Enterprises
uonick
Камил Киблис
Марс Яу
Мартин Латинов
Маликов Евгений
Андрес Эспиноза Арсе
Мэтью Уильямсон
Эндрю Брукс
Стив Ков
Стивен Виттен
Сильван Зеехольцер
Тони Шёнбухнер
Марек Томан
Декстер Фрейвалд
Чад Вест
Бонд Акинмад
AlpiSol - Эрнальдо Писати
Адам Уилкинс
Михай Флавиу Мольнар
Каролина Р Молла
Андрес Эспиноза Арсе
Ян Кремлачек
Эрик Шульц
Рикардо Андраде
Дерек Левен
Майкл Нельсон
Денис Бах
Ленард Османи

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

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *