Готовимся к php 7

Готовимся к php 7
image-3045

2015 год стал важный годом для PHP. Спустя одиннадцать лет после выпуска PHP 5.0, новая версия, наконец, готовится к выходу! PHP 7 выйдет до конца этого года, в результате чего мы получим много новых возможностей языка и впечатляющий прирост производительности.
Но как это повлияет на текущий ваш PHP код? Что действительно изменилось? Насколько это безопасно для обновления? Эта статья ответит на эти вопросы и покажет пару новинок которые придут с PHP 7.

Улучшения производительности

Производительность, несомненно, самая главная причина, почему вы должны обновить свои серверы, как только выйдет стабильная версия PHP. Рефакторинг ядра представленный в phpng RFC делает PHP 7, таким же быстрым (или даже быстрее чем) HHVM. Официальные тесты впечатляют, большинство реальных приложений, работающих на PHP 5.6 будет работать, по крайней мере в два раза быстрее на PHP 7.
Для получения подробной информации о тестах производительности, посмотрите на презентации Rasmus Лердорф. Вот показатели WordPress из этого доклада:

image-3046

PHP 7 обрабатывает в два раза больше запросов в секунду, что в практическом плане будет представлять улучшение производительности WordPress сайтов на 100%.

Обратная совместимость

Давайте поговорим о некоторых вещах, которые потенциально могут нарушить работоспособность приложения, работающие на старых версиях PHP.

Устаревшие элементы удалены

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

В частности, теги ASP-стиля (<%, <% = и %>), были удалены вместе с тегом сценариев (<script language=”php”>). Убедитесь, что вы используете рекомендуемый тег <?php. Другие функции, которые ранее были устаревшие, также были удалены в PHP 7.

Расширение EREG (и все ereg_* функции) были устаревшими, начиная с PHP 5.3. Они должны быть заменено с расширением PCRE (preg_* функции), который предлагает гораздо больше возможностей. Расширение MySQL (и mysql_* функции) были устаревшими, начиная с PHP 5.5. Для прямого перехода, вы можете использовать MySQLi расширение и mysqli_* функции вместо них.

Единый синтаксис переменных

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

<?php
class Person
{
   public $name = 'Erika';
   public $job = 'Developer Advocate';
}
$person = new Person();
$property = [ 'first' => 'name', 'second' => 'info' ];
echo "\nMy name is " . $person->$property['first'] . "\n\n";

В PHP 5, выражение $person->$property['first'] оценивается как $person->{$property['first']}. В практическом плане это будет интерпретироваться как $person->name, давая вам результат «My name is Erika». Даже если это крайний случай, это показывает четкие несоответствия с нормальным порядком вычисления выражения, слева направо.

В PHP 7, выражение $person->$property['first'] оценивается как {$person->$property}['first']. Интерпретатор оценить $person->$property в первую очередь; следовательно, предыдущий пример кода не будет работать в PHP7, потому что $property массива и не может быть преобразован в строку.

Быстрый и простой способ, чтобы исправить эту проблему, явно определяющий порядок оценки с помощью фигурных скобок (например, $person->{$property['first']}), который будет гарантировать такое же поведение как на PHP 5 и PHP 7.
Благодаря новой форме слева на права переменной синтаксиса, многие выражения ранее обработанные некорректно теперь работают без проблем. Чтобы проиллюстрировать это новое поведение, рассмотрим следующий класс:

<?php
class Person
{
   public static $company = 'DigitalOcean';
   public function getFriends()
   {
       return [
           'erika' => function () {
               return 'Elephpants and Cats';
           },
           'sammy' => function () {
               return 'Sharks and Penguins';
           }
       ];
   }
   public function getFriendsOf($someone)
   {
       return $this->getFriends()[$someone];
   }
   public static function getNewPerson()
   {
       return new Person();
   }
}

С PHP 7, мы можем создать вложенные ассоциации и различные комбинации между операторами:

$person = new Person();
echo "\n" . $person->getFriends()['erika']() . "\n\n";
echo "\n" . $person->getFriendsOf('sammy')() . "\n\n";

Этот фрагмент даст нам сообщение об ошибке в PHP 5, но работает, как ожидалось в PHP 7.

Аналогично, вложенными статического доступа также возможно:

echo "\n" . $person::getNewPerson()::$company . "\n\n";

В PHP 5, это даст нам классическую ошибку синтаксиса T_PAAMAYIM_NEKUDOTAYIM.

Фатальная ошибка с множественным «default» классами

Это, опять же, крайний случай, и это больше связано с логической ошибкой в коде. Там нет смысла для нескольких условий по умолчанию в коммутаторе, а потому, что он никогда не вызвало никаких проблем (например, без предупреждений), это может быть трудно обнаружить ошибку. В PHP 5, будет использоваться последний умолчанию, но в PHP 7 теперь будет получить Фатальная ошибка: переключатель заявления могут содержать только один пункт по умолчанию.

Исключения

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

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

<?php
set_error_handler(function ($code, $message) {
   echo "ERROR $code: " . $message . "\n\n";
});
function a(ArrayObject $b){
   return $b;
}
a("test");
echo "Hello World";

Этот код генерирует возмещаемую ошибку, вызванную несоответствием типа при вызове функции a(), используя строку в качестве параметра. В PHP 5, она генерирует E_RECOVERABLE и вы получите:

ERROR 4096: Argument 1 passed to a() must be an instance of ArrayObject, string given, called in /data/Projects/php7dev/tests/test04.php on line 12 and defined(...)
Hello World

Обратите внимание, что выполнение продолжается, потому что ошибка была обработана. В PHP 7, этот код генерирует исключение TypeError (не ошибка!), Так что обработчик ошибок не будет вызвана. Это вывод, который вы получите:

Fatal error: Uncaught TypeError: Argument 1 passed to a() must be an instance of ArrayObject, string given, called in /vagrant/tests/test04.php on line 12 and defined in /vagrant/tests/test04.php:7
Stack trace:
#0 /vagrant/tests/test04.php(12): a('test')
#1 {main}
  thrown in /vagrant/tests/test04.php on line 7

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

  • Throwable интерфейс
    • Исключение реализует Throwable
      • ErrorException распространяется исключение
      • RuntimeException распространяется исключение
    • Ошибка реализует Throwable
      • Ошибка типа распространяется Ошибка
      • ParseError распространяется Ошибка
      • AssertionError распространяется Ошибка

В основном это означает, что новый всеохватывающий Исключение теперь Throwable вместо Exception. Это не должно повлиять на любой унаследованный код, но держать его в уме при обращении новых исключений PHP 7.

Новые возможности языка

Давайте поговорим о наиболее интересных новых функций, которые будут доступны при обновлении до PHP 7.

Новые операторы

PHP 7 поставляется с двумя блестящими новыми операторами: spaceship (или сочетание операторов сравнения) и нулевого сливания оператор.
Оператор spaceship (<=>), также известный как комбинированного оператора сравнения, может быть использованы, чтобы сделать ваши блоки сравнение более кратким. Рассмотрим следующее выражение:

$a <=> $b

Это выражение будет -1, если $a меньше, чем $b, 0, если $a равен $b, и 1, если $a больше, чем $b. Раньше это было бы:

($a < $b) ? -1 : (($a > $b) ? 1 : 0)

Оператор null coalesce(??) также работает в качестве ярлыка для общего пользования в случае: условного авторства, который проверяет, если значение установлено, прежде чем использовать его. В PHP 5, вы, как правило, что-то вроде этого:

$a = isset($b) ? $b : "default";

С новым оператором в PHP 7, мы можем просто использовать:

$a = $b ?? "default";

Скалярные type-hint

Одна из самых обсуждаемых новых возможностях в PHP 7: скалярные type-hint будут доступны как типы для функций и методов. По умолчанию, скалярные типа не являются ограничительными, что означает, что если вы передаете значение с плавающей точкой в целое параметра, это будет просто заставить его Int без создания каких-либо ошибок или предупреждений.
Это возможно, однако, в строгом режиме, который будет выдавать ошибки при неверном типе переданном в качестве аргумента. Рассмотрим следующий код:

<?php
function double(int $value)
{
   return 2 * $value;
}
$a = double("5");
var_dump($a);

Этот код не будет генерировать какие-либо ошибки, потому что мы не используем строгий режим. Единственное, что будет происходить в преобразование типа, так что строка «5» передается в качестве аргумента будет принудительно преобразовано к целому числу внутри функции.
Если мы хотим, что бы только целые числа могли быть переданы в функцию, мы можем включить строгий режим DECLARE (strict_types = 1) в качестве самой первой строке в нашем сценарии:

<?php
declare(strict_types = 1);
function double(int $value)
{
   return 2 * $value;
}
$a = double("5");
var_dump($a);

Этот код будет генерировать фатальную ошибку: TypeError: Uncaught Argument 1 passed to double() must be of the type integer, string given.

Возвращение type-hint

Еще одна важная новая функция идет с PHP 7 это возможность определить тип возвращаемого значения метода и функций:

<?php
function a() : bool
{
   return 1;
}
var_dump(a());

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

Fatal error: Uncaught TypeError: Return value of a() must be of the type boolean, integer returned

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

Что дальше?

PHP 7 планирует выпустить стабильную версию в конце ноября. Бета-версия уже доступна для тестов. Проверьте RFC все изменения идут с PHP 7 для получения дополнительной информации.

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

Счастливые кодирования!

Введение CockpitCMS — CMS для разработчиков

В этой статье мы увидим, как использовать CockpitCMS, установку CMS на бэкенд и использование интерфейса API, который предоставляет Cockpit для создания специальных функций интерфейса.

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

Установка

CockpitCMS можно скачать здесь. После загрузки, просто распакуйте архив в папку на вашем веб-сервере. В моем случае, это HTTP: http://test.webtoks.ru/cockpit/

Затем, переходим на страницу установки CMS: http://test.webtoks.ru/cockpit/install, чтобы начать процесс установки.

ПРИМЕЧАНИЕ: Кокпит использует SQLite в качестве базы данных по умолчанию. Если вы еще не установили SQLite, сделайте это перед установкой.

ПРИМЕЧАНИЕ: Кокпит также требует, чтобы каталог /storage/data был доступен.

Установка одним кликом, когда установка будет завершена, вам увидите эту страницу:

1419552599installation[1]
image-827

Теперь мы можем войти с учетной записью администратора с логином и паролем admin, панель администратора будет иметь следующий вид:

INAZu7P6PSs[1]
image-828

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

Модули в Cockpit

Два наиболее важных модулей в Cockpit являются: коллекции и галереи.

Мы можем относиться к «коллекциям» как связке таблиц. Все коллекции определяется в Cockpit с различными полями практически всех типов. Коллекции заполняется «Элементами», который похож на запись в таблице.

Галереи являются «Фотоальбомами». Пользователь создает фотоальбом, который может содержать фотографии, которые могут быть использованы в дальнейшем.

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

Создать первую коллекцию

Для начала, я создам простую коллекцию. Мы должны написать имя для коллекции (Путешествия) и определить, какие поля она будет содержать:

l6DqDPmrNeU[1]
image-829

Это простая структура состоит из следующих полей:

  • name: текстовое поле
  • date: поле дата
  • location: текстовое поле
  • diary: поле markdown, чтобы записать некоторые основные моменты поездки
  • pic: текстовое поле, чтобы связать в галерею изображений

ПРИМЕЧАНИЕ: Cockpit также создает несколько другие полей автоматически, чтобы хранить информацию, такую id, дата создания, дата изменения и т.д. Мы также можем использовать эти мета поля в нашем коде.

Вы также можете заметить, что, хотя Cockpit поддерживает тип поля «Галерея», мы до сих пор используете поле «Текст». Это потому, что Cockpit пока не может связать существующую галерею в записи коллекции. Позже мы увидим, как обойти это. Мы можем создавать много коллекций, галерей.

rIhsjT-nINE[1]
image-830

Теперь, давайте перейдем к фронтенду.

Фронтенд

ПРИМЕЧАНИЕ: Мы будем использовать фреймворк Silex с Twig для фронтенда, но вы можете выбрать любой другой фреймворк, логика останется схожей.
После того как скачали Selix у нас получится следующая структура папок:

public_html/
├── cockpit/
├── silex/
├── views/
└── index.php

В папке views будут хранится наши шаблоны.

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

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

ПРИМЕЧАНИЕ: Для использования API Cockpit, необходимо подключить require_once __DIR__. '/../cockpit/bootstrap.php';

f9XINXQ8b1U[1]
image-831

Код приведен ниже:

$app->get('/', function () use ($app) {
    $collections = cockpit('collections:collections', []);
    $galleries = cockpit('galleries:galleries', []);
    return $app['twig']->render('index.html.twig', ['collections' => $collections, 'galleries' => $galleries]);
})->bind('home');

Мы получаем все коллекции и галереи с помощью API. Это очень просто.

Раздел коллекции могут быть отображены с помощью Twig:

<h2>Collections</h2>
<p>There are total <strong>{{collections|length}}</strong> collection(s) in the CMS:</p>
<ul>
{% for col in collections|keys %}
    <li>
        <a href="{{ url('collection', {col: col})}}">{{col}}</a>
    </li>
{% endfor %}
</ul>

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

ПРИМЕЧАНИЕ: VarDumper могут быть использованы в Silex. Чтобы использовать его, необходимо использовать Symfony\VarDumper; и добавить одну строку в composer.json

"symfony/var-dumper": "3.0.*@dev"

Получение Коллекций

$app->get('/', function () use ($app) {
    $collections = cockpit('collections:collections', []);
    $galleries = cockpit('galleries:galleries', []);
    return $app['twig']->render('index.html.twig', ['collections' => $collections, 'galleries' => $galleries]);
})->bind('home');
$app->get('/collection/{col}', function ($col) use ($app) {
    $entries = collection($col)->find()->toArray();
    foreach ($entries as &$entry) {
        $text = $entry['diary'];
        $html = MarkdownExtra::defaultTransform($text);
        $entry['diary'] = $html;
    }
    return $app['twig']->render('entries.html.twig', ['collection' => $col, 'entries' => $entries]);
}
)->bind('collection');

Получение галерей

$app->get('/gallery/{gal}', function ($gal) use ($app) {
    $images = cockpit("galleries")->gallery($gal);
    foreach ($images as &$img) {
        $image = $img['path'];
        $imgurl = cockpit('mediamanager:thumbnail', $image, 200, 200);
        $img['cache']=$imgurl;
        $path=$img['path'];
        $url=str_replace('site:', 'http://'.$app['request']->getHost().'/', $path);
        $img['url']=$url;
    }
    return $app['twig']->render('gallery.html.twig', ['images'=>$images, 'gal'=>$gal]);
}
)->bind('gallery');

Вывод

Cockpit легкая, простая в установке и настройке CMS. Создавать коллекций и галерей, заполнение запись в коллекции и загрузка изображений в галерее все очень просто.

У Cockpit  хороший API, для реализации в  фронтенде различных задач. Кокпит CMS лучше для тех разработчиков,  которые обладают определенным уровнем PHP, CSS и знаниями фреймворков, которые не желают быть связанными других тяжелыми CMS, и хотят создать простой, аккуратный сайт. Тем не менее, важно подчеркнуть, что это может увеличить время разработки.

Демонстрационный код для этой статьи можете посмотреть здесь.

11 Рекомендаций по разработке на PHP

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

1. Сообщения об ошибках, при разработке, должны быть включены.

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

2. Используйте DRY подход

DRY означает — не повторяй себя. Эта концепция является очень полезной концепцией программирования и должна быть использована в любом языке программирования, таких как Java, C# и PHP. Использование DRY подход мы гарантируем, что нет избыточного кода. Часть кода, который нарушает DRY подход называют WET решением. WET расшифровывается как — написать все, TWIC — мы наслаждаемся печататью. Давайте посмотрим на следующий код:

WET подход:

$mysql  = mysql_connect ( 'localhost',  'mysqladmin_uid', 'mysqladmin_pwd' );
mysql_select_db( 'DB_NAME' ) or die( "Sorry !! No database selected!");

Этот код основан на WET подходе, но все равно он рабочий.
После DRY подхода, код может быть обновлен:

$db_host = 'localhost';
$db_user = 'mysqladmin_uid';
$db_password = 'mysqladmin_pwd';
$db_database = 'DB_NAME';
$mysql = mysql_connect($db_host, $db_user, $db_password);
mysql_select_db($db_database);

3. Использование табыляции

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

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

Как и в любом языке программирования, в PHP также необходимо следовать стандартам именования. Есть два основных подхода что бы гарантировать это:

  • Использование Camel Case — при таком подходе первая буква в нижнем регистре а первой буква каждого следующего слова находится в верхнем регистре.
public class MyClass {
	public void methodName(String argName) {
	}
}
  • Использование подчеркивания между словами — в данном подходе, мы ставим знак подчеркивания (‘_’) между словами. Используя этот подход, код может быть изменен следующим образом:
public class MyClass {
public void method_name(String arg_name) {
}
}

5. Следует избегать глубокой вложенности

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

Пример использования излишней вложенности

public class MyClass {
public void method_name(String arg_name) {
if (is_writable($folder)) {
    			if ($fp = fopen($file_location_path,'w')) {
       			if ($stuff = extractSomeConditionalStuff()) {
         				if ( fwrite ( $fp, $stuff) )  {
         					// ...
         				}  else  {
         					return false;
         				}
} else {
     	return false;
}
} else {
 	return false;
}
} else {
	return false;
}
}
}

Как мы видим, здесь очень трудно понять, которые блок где заканчивается. Для лучшей читаемости, давайте модифицировать код:

function method_name (String arg_name) {
// ...
  	if (!is_writable($folder)) {
    		return false;
  	}
  	if (!$fp = fopen($file_location_path,'w')) {
    		return false;
  	}
  	if (!$stuff = extractSomeConditionalStuff()) {
    		return false;
  	}
  	if (fwrite($fp, $stuff)) {
   		// ...
  	} else {
    		return false;
  	}
}

6. Используйте адекватные комментарии

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

7. Не оставляете phpInfi() в корне сайта

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

8. Никогда не доверяйте пользователю

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

9. Используйте механизм кэша, где это требуется

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

        • Memcached — хранение небольшой информации в оперативной памяти парой ключ-значение
        • APC-Alternative PHP Cache открыты кэш opcode для PHP
        • XCache — быстрый надежный opcode кэш PHP
        • Zend Cache — набор API, для реализации расширенных возможностей кэширования.
        • eAcclerator- open source инструменты кэширования

10. Избегайте копирования глобальных переменных

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

$desc = strip_tags($_POST['PHP description']);
echo $desc;

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

echo strip_tags($_POST['PHP description']);

11. Используйте Фреймворки

Фреймворки делают нашу жизнь проще, поскольку они обеспечивают нас проверенными решениями. В PHP есть много доступных Фреймворков. Во время разработки, вы должны использовать их. Они так же использую подход MVC (Model View Controller).

Вывод

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