- Подробности
-
Категория: PHP. Система
1. Генерируем CSV
Часто в разных проектах встречаются попытки конвертировать многоразмерный массив данных в CSV с помощью подобного кода:
1 <?php
2 $csv = "";
3 foreach ($data as $row) {
4 $csv .= join(",", $row) . "n";
5 }
6 echo $csv;
Проблема заключается в том, что отдельные элементы не обрабатываются корректно. Значения с кавычками или запятой могут проскочить через дешифратор и позже распознаваться как данные CSV формата. Существенно лучше будет использовать встроенную функцию fputcsv(). Она должна выполняться быстрее, так как реализована на С, и обрабатывает все необходимые кавычки и разделители.
Следующий код представляет логику для построения потока вывода в формате CSV из массива данных. Опциональные параметры служат для указания заголовков столбцов и определения цели потока данный CSV — непосредственно браузер или строка. Поток данных обрабатывается с помощью функции fputcsv() для которой требуется дескриптор открытого файла.
01 <?php
02 function toCSV(array $data, array $colHeaders = array(), $asString = false) {
03 $stream = ($asString)
04 ? fopen("php://temp/maxmemory", "w+")
05 : fopen("php://output", "w");
06
07 if (!empty($colHeaders)) {
08 fputcsv($stream, $colHeaders);
09 }
10
11 foreach ($data as $record) {
12 fputcsv($stream, $record);
13 }
14
15 if ($asString) {
16 rewind($stream);
17 $returnVal = stream_get_contents($stream);
18 fclose($stream);
19 return $returnVal;
20 }
21 else {
22 fclose($stream);
23 }
24 }
С помощью функции toCSV() генерирование данных a формате CSV будет простым и надежным процессом.
2. Автозагрузка классов
Файлы автозагружаемых классов обычно располагаются в общем месте. Но вам может не нравится раздутый каталог или тяжеловесные автозагрузчики, которые имеются в большинстве библиотек PHP, или есть желание использовать собственное решение. к счастью, возможно использовать собственный минимальный загрузчик, который будет соответствовать стандарту PSR-0.
Стандарт не описывает функционал, который должен обеспечивать совместимый с PSR-0 автозагрузчик (методы регистрации, опции конфигурации и так далее). Если он может автоматически находить определение класса по шаблону пути <Имя производителя>(<Пространство имен>), то он соответствует PSR-0. Более того, нет жестких требований для директории шаблона <Имя производителя>. Дополнительным грузом большинства автозагрузчиков является соглашение о том, что нужно указывать расположение файлов в коде. Но в таком требовании нет необходимости, если просто используется директория в дереве включений PHP.
1 <?php
2 spl_autoload_register(function ($classname) {
3 $classname = ltrim($classname, "\");
4 preg_match('/^(.+)?([^\\]+)$/U', $classname, $match);
5 $classname = str_replace("\", "/", $match[1])
6 . str_replace(["\", "_"], "/", $match[2])
7 . ".php";
8 include_once $classname;
9 });
Магия данного кода заключается в использовании регулярного выражения, которое разделяет имя на составляющие части: имя класса попадет в $match[2], а в $match[1] будет содержаться название пространства имен (которое может быть и пустой строкой).
3. Разбор данных с фиксированной длиной с помощью функции unpack()
В современном мире, наполненном данными в формате XML и JSON, может показаться, что данные с фиксированной длиной вымерли… что будет роковой ошибкой. Существует большой объем данных, которые используют формат с фиксированной длиной: некоторые журнальные записи, MARC 21 (библиографическая информация), NACHA (финансовая информация), и тому подобное. Поэтому приходится беспокоиться о поддержке работы с таким данными.
Работа с данными в формате с фиксированной длиной относительно просто реализуется в языках программирования, подобных С. Так как после загрузки в память, данные выравниваются в соответствующие структуры. Но в динамических языках программирования, подобных PHP, работа с такими данными превращается в тяжкий труд, результатом которого часто становится появление следующего кода:
01 <?php
02 // Разбор заголовка записи NACHA
03 $row = fread($fp, 94);
04 $header = array();
05 $header["type"] = substr($row, 0, 1);
06 $header["priority"] = substr($row, 1, 2);
07 $header["immDest"] = substr($row, 3, 10);
08 $header["immOrigin"] = substr($row, 13, 10);
09 $header["date"] = substr($row, 23, 6);
10 $header["time"] = substr($row, 29, 4);
11 $header["sequence"] = substr($row, 33, 1);
12 $header["size"] = substr($row, 34, 3);
13 $header["blockFactor"] = substr($row, 37, 2);
14 $header["format"] = substr($row, 39, 1);
15 $header["destName"] = substr($row, 40, 23);
16 $header["originName"] = substr($row, 63, 23);
17 $header["reference"] = substr($row, 86, 8);
18 print_r($header);
Такой код слишком громоздок и уязвим для глупых, трудно выявляемых ошибок индексов. Но ему есть альтернатива: функция unpack().
Описание функции unpack() гласит: “Распаковывает данные из бинарной строки в массив согласно заданному формату” и представляет несколько примеров использования для данных в бинарном формате. Не вполне очевидно, что данная функция может быть использована для работы с данными в формате с фиксированной длиной благодаря коду формата ‘A’, который представляет символ (любая строка является набором битов и байтов).
С помощью функции unpack() выше приведенный пример можно изменить следующим образом:
1 <?php
2 // Разбор заголовка записи NACHA
3 $row = fread($fp, 94);
4 $header = unpack("A1type/A2priority/A10immDest/A10immOrigin/"
5 . "A6date/A4time/A1sequence/A3size/A2blockFactor/A1format/"
6 . "A23destName/A23originName/A8reference", $row);
7 print_r($header);
Строка формата в данном случае является серией кодов A, с указанием количества символов для соответствующего поля, и имени ключа для таблицы результата с разделением через слэш. Например, A6date соответствует 6 символам и будет доступно как $header["date"].
4. Шаблоны HTML
В сообществе PHP постоянно идут споры о шаблонах. Все соглашаются с тем, нужно разделять HTML и PHP, но столкновения начинаются в вопросах использования библиотек шаблонизаторов, таких как Smarty или Twig. Одни говорят, что PHP сам по себе является шаблонизатором и выдвигают аргументы о дополнительном синтаксисе, скорости библиотек и так далее. Другие указывают на преимущества расширения функционала серверного языка программирования. Компромисом может стать использование минимума классов PHP для собственного шаблона HTML.
01 <?php
02 class Template
03 {
04 protected $dir;
05 protected $vars;
06
07 public function __construct($dir = "") {
08 $this->dir = (substr($dir, -1) == "/") ? $dir : $dir . "/";
09 $this->vars = array();
10 }
11
12 public function __set($var, $value) {
13 $this->vars[$var] = $value;
14 }
15
16 public function __get($var) {
17 return $this->vars[$var];
18 }
19
20 public function __isset($var) {
21 return isset($this->vars[$var]);
22 }
23
24 public function set() {
25 $args = func_get_args();
26 if (func_num_args() == 2) {
27 $this->__set($args[0], $args[1]);
28 }
29 else {
30 foreach ($args[0] as $var => $value) {
31 $this->__set($var, $value);
32 }
33 }
34 }
35
36 public function out($template, $asString = false) {
37 ob_start();
38 require $this->dir . $template . ".php";
39 $content = ob_get_clean();
40
41 if ($asString) {
42 return $content;
43 }
44 else {
45 echo $content;
46 }
47 }
48 }
Представленный код не является полноценной системой для создания шаблонов. Это все лишь вспомогательный класс для сбора пар ключ/значение, к которым можно получить доступ во включённом файле, назначенном в качестве шаблона. Сначала в виде создаем экземпляр класса Template, которому можно передать имя директории для поиска последовательных файлов шаблона (для группировки связанных файлов). Затем определяем значения, которые будут заполнять шаблон, с помощью метода set() или свойств. Как только значения указаны, можно вызывать метод out()для формирования шаблона.
01 <?php
02 $t = new Template();
03 // Устанавливаем значение для свойства
04 $t->greeting = "Приветсвие";
05 // Устанавливаем значение с помощью метода set()
06 $t->set("number", 42);
07 // Устанавливаем несколько значений с помощью метода set()
08 $t->set(array(
09 "foo" => "zip",
10 "bar" => "zap"
11 ));
12 // Выводим шаблон
13 $t->out("mytemplate");
Файл mytemplate.php для примера может иметь следующий вид:
01 <!DOCTYPE html>
02 <html lang="ru">
03 <head>
04 <meta charset="utf-8">
05 …
06 </head>
07 <body>
08 <div role="main">
09 <h1><?=$this->greeting;?></h1>
10 …
11 </div>
12 </body>
13 </html>
В файле шаблона имеется доступ ко всем значениям.
Второй параметр метода out() определяет возвращение содержания шаблона в виде строки, вместо передачи в браузер, что дает возможность использовать замещение в одном шаблоне результатами формирования другого.
5. Используем file_get_contents как альтернативу cURL
cURL — отличная библиотека для соединения через различные протоколы. Она имеет полноценный набор функций и может использовать для решения практически любой задачи коммуникации. Но основная часть каждодневного использования cURL в PHP связана с запросами HTTP GET и POST, и часто может быть легко заменена с помощью встроенных функций PHP.
Проблема использования cURL для запросов HTTP имеет два аспекта: 1) нужно устанавливать много опций, даже для простейшей транзакции; 2) она является расширением, которое может быть недоступно на сервере хостера.
file_get_contents() и stream_context_create() являются встроенными функциями PHP, доступными с версии 4.3. Они вместе могут быть использованы для выполнения большинства типов запросов, выполняемых через cURL.
2 $html = file_get_contents("http://example.com/product/42");
14 $html = file_get_contents("http://example.com/upload.php", false, $context);
Выше приведенный пример показывает загрузку файла с помощью запроса POST с массивом содержания, в котором необходимая для транзакции информация формируется с помощью ключей “method”, “header” и “content”.
При использовании функции file_get_contents() для сложных запросов, таких как загрузка файлов, может быть полезным создание макета веб формы и анализ процесса ее передачи на сервер с помощью инструментов разработчика (например, Firebug для Firefox), чтобы определить необходимые включения в заголовок запроса.
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: phpmaster.com/5-inspiring-and-useful-php-snippets/
Перевел: Сергей Фастунов