В по-голямата част от PHP кода ми е OOP. Но все пак имам и няколко функции, като три от тях бих искал да споделя тук. Те са tag / func_array_cut / profile.
Функцията tag
Както се и казва функцията tag генерира html тагове. Тъй като в 99% от времето PHP връща html, е много важно да имам нещо с което бързо и лесно да си създавам тагове. Основно тази функция я използвам в различни помощни методи:
function tag($tag, $options, $content = null){
if (is_string($options) && !is_string($content)){
list($content, $options) = array($options, $content);
}
$attributes = '';
if (is_string($options)){
$attributes = ' ' . $options;
} else if (is_array($options)){
foreach($options as $key => $value){
$attributes .= ' ' . $key . '="' . htmlspecialchars($value, ENT_COMPAT, 'utf-8') . '"';
}
}
return '<' . $tag . $attributes . (is_string($content) || strlen($content) > 0 ? ">{$content}</{$tag}>" : ' />');
}
Таg може да се извиква по няколко начина, като основната ми идея беше да не се налага да се замислям кои аргумент какъв е – атрибут или текст.
// <input type="text" value="text" />
tag('input', array('type' => 'text', 'value' => 'text'));
// <input type="text" value=""qoute" text" />
tag('input', array('type' => 'text', 'value' => '"qoute" text'));
// <div>content in div</div>
tag('div', 'content in div');
// 3 начина за генериране на
// <a href="http://www.pixeldepo.com">Pixeldepo</a>
tag('a', array('href' => 'http://www.pixeldepo.com'), 'Pixeldepo');
tag('a', 'Pixeldepo', array('href' => 'http://www.pixeldepo.com'));
tag('a', 'href="http://www.pixeldepo.com"', 'Pixeldepo');
Функцията array_cut
Едно нещо което е изключително досадно в STRICT режима на PHP, е непрекъснатите проверки isset / empty за това дали в даден масив има даден ключ. Затова създадох array_cut, тя проверява дали в дадения масив го има ключа и ако го има му връща стойността, ако я няма връща $default стройност. Като същевременно ключът се изтрива от оригиналния масив.
Това като се замисля е първата функция която написах за PHP framework-а който използвам ControlDepo 3.
function array_cut(array &$array, $key, $default = null){
if (!isset($array[$key])){
return $default;
}
$value = $array[$key];
unset($array[$key]);
return $value;
}
Тази функция е изключително полезна и може да се използва в редица случаи, ето два примера:
// това може да се напише така:
$name = isset($_POST['name']) ? $_POST['name'] : '[no-name]';
// може да се напише така:
$name = array_cut($_POST, 'name', '[no-name]');
// използване на array_cut за примерна функция за генериране на url-та
function url($options){
$url = '/' . join('/', array_filter(array(
array_cut($options, 'controller'),
array_cut($options, 'action', 'index'),
array_cut($options, 'id')
)));
if ($query = http_build_query($options)){
$url .= '?' . $query;
}
return $url;
}
// използване
// -> /products/view/1
url(array('controller' => 'products', 'action' => 'view', 'id' => 1));
// -> /users/index?page=1
url(array('controller' => 'users', 'page' => 1));
// -> /index?sort=name
url(array('sort' => 'name'));
Преди време си мислех, че в PHP5.3/6 смисълът от функцията ще се намали след като се добавиха ?: и ifsetor. Но просто ?: не е толкова мощен колкото ми се искаше, а ifsetor няма да го има.
Функцията profile
Докато другите 2 функции ги използвам много (и също така цялото ControlDepo 3 ги ползва). Функцията profile() е просто бърз начин за замерване, докато работя. В действителност тази функция се използва чрез чрез друга моя функция p(), която просто вика profile(), но записва резултата в лога на request-a и така малко по-лесно може да го анализирам резултата:
function profile($scope = '__default__'){
static $time = array();
if (isset($time[$scope])){
return microtime(true) - array_cut($time, $scope, 0);
}
$time[$scope] = microtime(true);
}
Тя се ползва просто така:
// имаме 2 нива на profile
profile('test');
sleep(1);
profile();
sleep(1);
echo profile(), "\n";
echo profile('test');
Надявам се тези 3 функции да са полезни на някои и ако някои има идеи как може да се подобри някоя от тях, ще се радвам да го сподели.