Поговорим о PHP // PHP

Хотел было назвать статью «профессиональное PHP программирование», но по факту — это лишь «заметки бывалого», которые будут полезны начинающим разработчикам, хотя, возможно, привлеку внимание и «старшего» поколения ;)
Инструментарий
Хороший мастер работает лишь со своим инструментом, и сильно расстраивается когда оного нет под рукой, так и я — всё своё ношу с собой:
- IDE — PHP Storm
- Менеджер БД — SQLYog
- Всяко-разно — notepad++, putty, winscp…
PHP Storm
IDE решает многие задачи и проблемы, которые постоянно возникают перед разработчиком. Мой выбор остановился на PHP Storm, а до того я успел попробовать Zend Studio, Eclipse, Aptana, NetBeans и еще несколько о которых и не вспомню. Что же хорошего в данной IDE:
- java — т.е. нам практически любая платформа по плечу
- автодополнение — очень адекватное, и приучает к документированию кода
- автосохранение — забудьте про ctrl+s
- автозаливка (FTP/SFTP)
- автозаливка после комита
- исправление ошибок
- поддержка VCS
- рефакторинг
- поиск и замена по файлам – работает просто отлично, и частенько меня выручала
- отличная поддержка HTML/CSS/JS
- Zen coding из коробки (советую таки узнать что это ;)
Но без недостатков не бывает:
- java — т.е. любит память, и IDE приходится время от времени перезапускать — где-то раз в неделю
- цена — сейчас, со скидкой, это $50 (до 27-го ноября)
Отдельно оговорюсь насчет цены — у меня купленная версия, но так же есть Open Source лицензия, ее тоже можно получить, но только надо запастись терпением (как можно догадаться — у меня терпения не хватило). Насчет же NetBeans — задолбал он своей нестабильной работой и такими же обновлениями.
В качестве заключения: мои слова ничего не значат, верьте своим глазам — попробуйте триал, благо целого месяца хватит на распробовать ;)
SQLYog
Для работы с MySQL использую SQLYog, что же в нём такого хорошего:
- автодополнение
- профайлер
- автоформатирование запросов
- синхронизация структуры БД и данных при необходимости
- SSH туннель — если у вас есть SSH, то SQLYog в игре
- HTTP туннель — хотя хватит доступа и к FTP
- отлично работает под wine (по правде говоря есть огрехи, но совсем мелкие)
Ну не без ложки дёгтя:
- цена — от $69, но есть триальная и урезанная фришная версия
Опять же, есть триал — пробуйте, и забудьте про phpMyAdmin как про страшный сон.
Ещё чуть-чуть
Ой, ну дальше дело вкуса:
- Notepad++ — всегда на подхвате, открывает большие файлы, понимает все кодировки, с плагином hex-редактор
- PuTTY — без него никак, (puttygen рулит кстати)
- TotalCmd – файловый менеджер + FTP клиентб недавно вышла 8-ая версия (beta), не купил, жмакаю раз в неделю кнопку с циферкой
- WinScp – SFTP клиент (файловый менеджер over SSH)
Да, я работаю на винде, набор инструментов для Linux и Мас отличается лишь набором дополнительных тулзов…
Фишки PHP и 5.3 в частности
phpDocumentor
Я уже упоминал о крутом автодополнение в IDE, тук вот, чтобы этого добиться необходимо описывать классы, методы и функции используя doc comment’ы:
/** * @property integer $id * @property string $login * ... */ class Row { }
В результате IDE будет подсказывать нам всё что нужно:
Еще примерчик:
/** * @return Users\Row */ function getUser() { return Registry::get("user"); } /* @var Users\Row $user */ $user = Registry::get("user");
В IDE похожий результат:
Кроме бенефитов для IDE есть еще возможность сгенерировать техническую документацию используя PHPDocumentor:
/** * <code> * $this->getByLoginOrPasswordAndEmail( * 'vasya', md5(123456), 'vasya@mail.ru' * ) * </code> */ function getByColumnsFinder() { /*...*/ }
Обернётся в:
Tips & Tricks: Fixme Comment
Заметки на будущее прям в коде:
// TODO: do something with some function // FIXME: hands // XXX: may be broken
IDE нынче умные пошли, и все такие заметки соберут до кучи:
Tips & Tricks: о include и require
А вы смотрели что возвращают функции include и require? А если в подключаемом файле используется return?
$config = require 'config.php'; // config.php return array( 'DB' => array(...) );
Достаточно универсальный способ для подключения конфигурационных файлов.
Tips & Tricks: о фильтрации данных
На дворе уже закат PHP 5.2, а фильтры не используем:
// return string or false filter_var('bob@example', FILTER_VALIDATE_EMAIL); filter_var('bob@example.com', FILTER_VALIDATE_EMAIL); // return string or false filter_var('http://example.com', FILTER_VALIDATE_URL);
По теме:
- http://www.php.net/manual/en/function.filter-var.php
- http://www.php.net/manual/en/filter.filters.validate.php
- http://www.php.net/manual/en/function.filter-var-array.php
Иногда обработку массива превращают в что-то невообразимое, можно же проще:
// array of ids $ids = $Request->getParam("ids"); // to integer $ids = array_map("intval", $ids); // without zero $ids = array_filter($ids); // unique $ids = array_unique($ids); // prepare for SQL $idsStr = join(",", $ids);
А бывают ситуации, когда в форме есть несколько submit кнопок, и надо понимать что же было нажато (о да, это плохие формы)
<form> ... <input type="submit" name="disable" value="Disable selected" /> <input type="submit" name="enable" value="Enable selected" /> </form>
// gets current action $action = current(array_intersect(array_keys( $_REQUEST), array('disable', 'enable') ));
Tips & Tricks: glob
Уже везде упоминали функцию glob, но мы всё так же её игнорируем, так что я решил её опять вспомнить:
$controllers = glob('/modules/*/controllers/*.php'); $modules = glob('/modules/*', GLOB_ONLYDIR);
Tips & Tricks: mysqlnd
Если у вас высокопроизводительное приложение, если вам знакомо понятие master и slave, если разруливаете это ручками, то вот оно — прозрение:
// in config [myapp] master[]=localhost:/tmp/mysql.sock slave[]=192.168.2.27:3306 // in sources $mysqli = new mysqli("myapp", "username", "password", "database"); $pdo = new PDO("mysql:host=myapp;dbname=database", "username", "password");
По теме:
- http://www.php.net/manual/en/book.mysqlnd.php
- Replication and load balancing mysqlnd plugin for all PHP MySQL extensions released
P.S. О, это уже было в … твитере ;)
Reflection
Посмотри на себя в зеркало, в нём ты увидишь и имена методов, и приватные данные, и даже комментарии. Знай и используй с умом!
PHP 5.3
Приведу краткие тезисы по теме новшеств в PHP 5.3 (да, да, жевано-пережевано, но повторить то стоит)
Анонимные функции
Используете jQuery, значит ничего нового тут не увидите:
$ids = array_map(function($el){ return intval($el); }, $ids); // or $toInt = function($el){ return intval($el); }; $ids = array_map($toInt, $ids); // or $int = $toInt($el);
Замыкания
Смотреть в код до наступления понимания происходящего:
function getTimeout() { $el = "15 minutes"; return function() use ($el){ return intval($el); }; } $timeOut = getTimeout(); echo $timeOut(); // >> 15
Магический метод __invoke()
Вместо слов, лишь код:
class Row { function __invoke() { return $this->login; } } $user = new Users\Row(); $var = $user(); // >> return user login
Namespaces
Про пространство имён не писал лишь ленивый, но я предлагаю простую ассоциацию c файловой системой (спасибо за бэкслеш, ассоциация будет с Windows):
\ << Default namespace - root \Exception \StdClass \Application << Our namespace - Application \Model \User \Group \Controller \User
- объявляя namespace — мы добавляем новый класс в иерархию «папок» — cd && mkdir
- говоря use — используем директорию из иерархии (1 или более) — как команда cd
- говоря use as — используем под определенным именем — ln
- всегда можно обращаться идя от корня (абсолютный путь: \Application\Model\Group)
Позднее статическое связывание
Эта непонятная фигня означает, что когда вы наследуете класс от статического, то у вас возникнут проблемы с доступом к статическим методам наследуемого класса, приведу наглядный (я надеюсь) пример:
class Latin { const CHARS = 'abc...'; static function getChars() { return self::CHARS; } } class French extends Latin { const CHARS = 'aàábc...'; } echo French::getChars(); // >> abc...
В PHP 5.3 решается просто:
class Latin { const CHARS = 'abc...'; static function getChars() { return static::CHARS; // << static } } class French extends Latin { const CHARS = 'aàábc...'; } echo French::getChars(); // >> aàábc...
Почти фреймворк
Ой, велосипед, да на «новых» технологиях, нямочка, зацените-ка контроллер:
namespace Bluz; return /** * @acl View User Profile * @cache 5 minutes * @param integer $id * @return closure */ function($id) use ($bootstrap, $app, $view) { /** * @var closure $bootstrap * @var Application $app * @var View $view */ $view->user = $app->getDb()->getRow("...", array($id)); };
- Контроллер — анонимная функция возвращаемая при подключении файла
- Может вернуть что угодно, лишь бы было callable
- Принимает параметры с реквеста, уже отфильтрованнные (описали же в doccomment’e правила)
- Кеширует результат выполнения на 5 минут (опять reflection)
- Acl тут тоже не просто так ;)
Возможно выложим на общее обозрение сие творение, ну когда отшлифуем его ;)
Если что-то позабыл
Позабыл я о небольшом изменении в поведении тернарного оператора «(statement)?(then):(else)», у него появилось мини-сокращение:
echo $var?$var:'nil'; // ? : improvements echo $var?:'nil';
Что-то оно не очень, можно было сделать лучше (эти примеры не работают!):
echo $var?; // or echo isset($var['elem'])?$var['elem'];
Еще «незаслужено» обошёл стороной метки:
// labels start: echo "start"; goto finish; echo "never"; finish: echo "finish";
P.S. Всё это и еще немного больше я обычно рассказываю на лекциях в своём отделе ;)