9 Корисних PHP функцій

Огляд декількох PHP функцій які можуть бути корисні в різних повсякденних завданнях. Будь то ви кодер з досвідом, чи початківець розробник.

1. Функції з довільним числом аргументів

PHP дозволяє визначати функції з необов'язковими аргументами. Але існує також метод, який дозволяє використовувати повністю довільне число аргументів функції.

Для прикладу, візьмемо функції з необов'язковими аргументами:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Функція з двома довільними аргументами
function foo ($ arg1 ='', $ arg2 ='') {

    echo "arg1: $ arg1 n";
    echo "arg2: $ arg2 n";

}

foo ('hello', 'world');
/ * Результат:
arg1: hello
arg2: world
*/

foo ();
/ * Результат:
arg1:
arg2:
* /

Тепер, давайте подивимося, яким чином ми можемо побудувати функцію, яка приймає будь-яку кількість аргументів. Використовуємо функцію func_get_args ();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 26
//Список аргументів може бути порожнім
function foo () {

    //Повертає масив всіх переданих аргументів
    $ Args = func_get_args ();
    foreach ($ args as $ k =>$ v) {
        echo "arg". ($ k +1). ": $ v n";
    }

}

foo ();
/ * Нічого не виведе */

foo ('hello');
/ * Результат:
arg1: hello
*/

foo ('hello', 'world', 'again');
/ * Результат:
arg1: hello
arg2: world
arg3: again
* /

2. Використовуємо Glob () для пошуку файлів

Більшість PHP функцій мають наочні імена. Наприклад функція glob (); за якою відразу не скажеш що вона робить, якщо ви з нею не знайомі.

Як альтернативну функцію для пошуку файлів, можна розглядати scandir (); . Ця функція дозволити вам шукати файли за шаблоном.

Пошук файлів функцією glob ();

1
2
3
4
5
6
7
8
9
10
11
12
13
//Пошук всіх php файлів
$ Files = glob ('*. php ');

print_r ($ files);
/ * Результат:
Array
(
    [0] =>phptest.php
    [1] =>pi.php
    [2] =>post_output.php
    [3] =>test.php
)
* /

Для пошуку декількох типів файлів:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Пошук всіх php і txt файлів
$ Files = glob ('*.{ php, txt} ', GLOB_BRACE);

print_r ($ files);
/ * Результат:
Array
(
    [0] =>phptest.php
    [1] =>pi.php
    [2] =>post_output.php
    [3] =>test.php
    [4] =>log.txt
    [5] =>test.txt
)
* /

Пошук файлів мають зворотний шлях:

1
2
3
4
5
6
7
8
9
10
$ files = glob ('../ images/a *. jpg ');

print_r ($ files);
/ * Результат:
Array
(
    [0] =>../images/apple.jpg
    [1] =>../images/art.jpg
)
* /

Якщо ви хочете отримати повний шлях до кожного файлу, можна просто викликати realpath ();

1
2
3
4
5
6
7
8
9
10
11
12
13
$ files = glob ('../ images/a *. jpg ');

//Застосовує функцію до кожного елементу масиву
$ Files = array_map ('realpath', $ files);

print_r ($ files);
/ * Результат:
Array
(
    [0] =>C: wamp www images apple.jpg
    [1] =>C: wamp www images art.jpg
)
* /

3. Інформація про використаної пам'яті (RAM)

Досить важливий фактор, при розробці. Адже основна мета оптимізації коду, це зменшення споживаних ресурсів.

Об'єм пам'яті, що використовується в сценарії може змінюватися під час виконання. Щоб отримати поточне використовується значення пам'яті, використовуємо функцію memory_get_usage (); , і щоб отримати найбільший (піковий) обсяг пам'яті, що використовується в будь-який момент виконання скрипта, використовуємо функцію memory_get_peak_usage (); .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
echo "Initial:". memory_get_usage ()." bytes n ";
/ * Результат
Initial: 361400 bytes
*/

//Використовуємо частину пам'яті
for ($ i = 0; $ i     $ Array [] = md5 ($ i);
}

//Видаляємо частина масиву
for ($ i = 0; $ i unset ($ array [$ i]);
}

echo "Final:". memory_get_usage ()." bytes n ";
/ * Результат:
Final: 885912 bytes
*/

echo "Peak:". memory_get_peak_usage ()." bytes n ";
/ * Результат:
Peak: 13687072 bytes
* /

3. Інформація про використання процесора (CPU)

Другий важливий фактор, а може і навіть перший по відношенню до пам'яті. Якщо RAM ми можемо додати, одну, дві планочки, то з процесорним часом у нас глухий кут, і використовувати його потрібно максимально раціонально.

Для цього ми будемо використовувати функцію getrusage (); . Так-таки варто пам'ятати що дана функція не доступна на Windows платформах.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
print_r (getrusage ()); / * Результат:
Array
(
    [Ru_oublock] =>0
    [Ru_inblock] =>0
    [Ru_msgsnd] =>2
    [Ru_msgrcv] =>3
    [Ru_maxrss] =>12692
    [Ru_ixrss] =>764
    [Ru_idrss] =>3864
    [Ru_minflt] =>94
    [Ru_majflt] =>0
    [Ru_nsignals] =>1
    [Ru_nvcsw] =>67
    [Ru_nivcsw] =>4
    [Ru_nswap] =>0
    [Ru_utime.tv_usec] =>0
    [Ru_utime.tv_sec] =>0
    [Ru_stime.tv_usec] =>6269
    [Ru_stime.tv_sec] =>0
)

* /

Описувати всі значення немає сенсу, а варто лише виділити основні: user time і system time . У результаті це останні чотири значення, кожне з яких вимірюється в секундах і мілісекундах.

Розглянемо їх окремо:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Чекати 3 секунди
sleep (3);

$ Data = getrusage (); echo "User time:".
    ($ Data ['ru_utime.tv_sec'] +
    $ Data ['ru_utime.tv_usec']/1000000);
echo "System time:".
    ($ Data ['ru_stime.tv_sec'] +
    $ Data ['ru_stime.tv_usec']/1000000);

/ * Результат у секундах
User time: 0.011552
System time: 0
* /

Отже, як ви бачите, завантаження процесора і фактичної тривалості виконання, не завжди те ж саме. Так як скрипт очікує 3 секунди для виконання, завантаження процесора практично немає.

Є багато інших завдань, які можуть виконуватися в реальному часі, але можуть не використовувати процесорного часу, так як очікують операції з диском.

Як приклад, наступний скрипт:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Цикл 10 мільйонів разів
for ($ i = 0; $ i
}

$ Data = getrusage (); echo "User time:".
    ($ Data ['ru_utime.tv_sec'] +
    $ Data ['ru_utime.tv_usec']/1000000);
echo "System time:".
    ($ Data ['ru_stime.tv_sec'] +
    $ Data ['ru_stime.tv_usec']/1000000);

/ * Результат:
User time: 1.424592
System time: 0.004204
* /

Як ми бачимо, це зайняло близько 1,4 секунд процесорного часу, майже всі з яких був час користувача, так як не було ніяких системних викликів.

System Time - це кількість часу центрального процесора, який витрачається на виконання системних викликів для ядра від імені програми.

Як приклад:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ start = microtime (true);
//Викликаємо microtime протягом 3 секунд
while (microtime (true) - $ start
}

$ Data = getrusage (); echo "User time:".
    ($ Data ['ru_utime.tv_sec'] +
    $ Data ['ru_utime.tv_usec']/1000000);
echo "System time:".
    ($ Data ['ru_stime.tv_sec'] +
    $ Data ['ru_stime.tv_usec']/1000000);

/ * Результат:
User time: 1.088171
System time: 1.675315
* /

Тепер у нас зовсім мало часу використання системи. Це тому, що сценарій викликає функцію microtime (); багато разів, яка виконує запит через ОС для отримання часу.

Також ви можете помітити, що цифра в сумі не зовсім дотягує до 3-х секунд. Це тому, що, були інші процеси на сервері, а також сценарій не використовує 100% CPU на весь час виконання, в задані нами 3 секунди.

5. Магічні константи

PHP містить корисні магічні константи для отримання:

(__LINE__) - номер поточного рядка;
(__FILE__) - шлях до файлу;
(__DIR__) - шлях до каталогу;
(__FUNCTION__) - ім'я функції;
(__CLASS__) - ім'я класу;
(__METHOD__) - ім'я методу;
(__NAMESPACE__) - поточний простір імен.

Ми не будемо розглядати кожну з них у цій статті, але розглянемо приклад їх використання. Коли потрібно довантажити інші скрипти, зручно використовувати (__FILE__) або (__DIR__) починаючи з PHP 5.3.

1
2
3
4
5
6
7
8
//Це відносний шлях завантаження сценаріїв
//Який може привести до проблем при запуску
//Сценаріїв з різних каталогів
require_once ('config/database.php');

//Це завжди відносний шлях цього файлу
//Де б він не був виконаний
require_once (dirname (__FILE__). '/ config/database.php');

Використання (__LINE__), тим самим спрощуємо налагодження. Залежить від рядка в скрипті, на якій ця константа вказана. Нечутлива до регістру.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Деякий код
//...
my_debug ("some debug message", __LINE__);
/ * Результат:
Line 4: зневадження
*/

//Ще деякий код
//...
my_debug ("another debug message", __LINE__);
/ * Результат:
Line 11: Інше зневадження
*/

function my_debug ($ msg, $ line) {
    echo "Line $ line: $ msg n";
}

6. Створення унікальних ідентифікаторів

Можуть бути ситуації, коли вам потрібно створити унікальний рядок/значення. Багато хто використовує функцію md5 (); , хоча вона не зовсім призначена для цієї мети:

1
2
3
4
5
6
//Створюємо унікальний рядок
echo md5 (time (). mt_rand (1,1000000));
/ * Результат:
b253a5d3823951d533e70691e3efb08e
* /

Існує насправді інша функція, uniqid (); яка повинна бути використана спеціально для цього:

1
2
3
4
5
6
7
8
9
10
11
//Генерувати унікальний рядок
echo uniqid (); / * Результат:
4bd67c947233e
*/

//Генерувати ще одну унікальну рядок.
echo uniqid (); / * Результат:
4bd67c9472340
* /

Можна помітити, що, хоча рядки є унікальними, але вони мають однакові значення на початку. Це тому, що отримання рядків, пов'язане з серверним часом. Це насправді має приємний побічний ефект, так як кожен новий ідентифікатор отримуємо пізніше в алфавітному порядку, так що вони можуть бути відсортовані.

Щоб зменшити шанси на отримання дублів, ви можете передати префікс, або, другий параметр для збільшення ентропії:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//З префіксом
echo uniqid ('foo_');
/ * Prints
foo_4bd67d6cd8b8f
*/

//Збільшуємо ентропію
echo uniqid ('', true);
/ * Результат:
4bd67d6cd8b926.12135106
*/

//Обидва варіанти
echo uniqid ('bar_', true);
/ * Результат?
bar_4bd67da367b650.43684647
* /

Ця функція буде генерувати більш короткі строки, ніж md5 (); , яка також допоможе заощадити чимало місця в БД.

7. Серіалізация

Бувають потреби, коли потрібно перетворити масиви або об'єкти у форматі рядків. Інакше кажучи загнати масив в у файл, а потім його благополучно витягувати. Є дві функції серіалізациі змінних: serialize (); і unserialize (); .

Функція serialize (); повертає упакований варіант якогось об'єкта, а unserialize (); робить все навпаки, тобто приймає запакований варіант, а повертає нормальний варіант, який був до упаковки.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 26
27
28
29
30
31
32
33
34
//масив
$ Myvar = array (
    'Hello',
    42,
array (1, 'two'),
    'Apple'
);

//Перетворимо в рядок
$ String = serialize ($ myvar);

echo $ string;
/ * Резуьтат:
a: 4: {i: 0; s: 5: "hello"; i: 1; i: 42; i: 2; a: 2: {i: 0; i: 1; i: 1; s: 3: "two";} i: 3; s: 5: "apple";}
*/

//Отримуємо оригінальну змінну
$ Newvar = unserialize ($ string);

print_r ($ newvar);
/ * Результат:
Array
(
    [0] =>hello
    [1] =>42
    [2] =>Array
        (
            [0] =>1
            [1] =>two
        )

    [3] =>apple
)
* /

Це був рідний php'шний метод серіалізациі. Однак, так як JSON став настільки популярним в останні роки, вони вирішили додати його підтримку починаючи з PHP 5.2.

Тепер можна використовувати функції json_encode (); і json_decode (); :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 26
27
28
29
30
31
32
33
34
//масив
$ Myvar = array (
    'Hello',
    42,
array (1, 'two'),
    'Apple'
);

//Перетворимо масив
$ String = json_encode ($ myvar);

echo $ string;
/ * Результат:
["Hello", 42, [1, "two"], "apple"]
*/

//Отримуємо оригінальну змінну
$ Newvar = json_decode ($ string);

print_r ($ newvar);
/ * Результат:
Array
(
    [0] =>hello
    [1] =>42
    [2] =>Array
        (
            [0] =>1
            [1] =>two
        )

    [3] =>apple
)
* /

Як бачимо, вона є більш компактною, і краще за все, сумісної з JavaScript і багатьма іншими мовами. Тим не менш, для складних об'єктів, деяка інформація може бути втрачена.

8. Стиснення рядків

Коли мова йде про стиснення, ми зазвичай думаємо про файли, таких як ZIP архіви. Але як ви вже зрозуміли, можна стиснути довгі рядки засобами PHP, без участі будь-яких архіваторів.

З стисненням рядків, теж все просто. Для цього використовують наступні дві функції: gzcompress (); і gzuncompress (); .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ string =
"PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML.";

$ Compressed = gzcompress ($ string);

echo "Original size:". strlen ($ string). " n";
/ * Результат:
Original size: 800
*/

echo "Compressed size:". strlen ($ compressed). " n";
/ * Результат:
Compressed size: 418
*/

//Отримати назад
$ Original = gzuncompress ($ compressed);

Завдяки цим функціям, можна отримати достатню стиснення.

9. Реєстрація завершення роботи функції

Функція register_shutdown_function (); яка дозволить вам виконати певний код, прямо перед завершенням роботи сценарію.

Ви хочете захопити частину базових статистичних даних, в кінці вашого скрипта, наприклад, як довго він виконувався:

1
2
3
4
5
6
7
8
9
10
//Захоплення початку часу
$ Start_time = microtime (true);

//Ваш код
//...

//Показуємо час виконання сценарію
echo "execution took:".
        (microtime (true) - $ start_time).
        "Seconds .";

На перший погляд це може здатися тривіальним. Ви просто додали код на самій нижній частині сценарію, і він працює до його завершення. Однак, якщо ви ніколи не викличте функцію exit (); , то код ніколи не буде працювати. Крім того, якщо існує фатальна помилка, або, якщо сценарій припинений користувачем (Був натиснутий стоп в браузері), знову-таки, може не працювати:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ start_time = microtime (true);

register_shutdown_function ('my_shutdown');

//Ваш код
//...

function my_shutdown () {
    global $ start_time;

    echo "execution took:".
            (microtime (true) - $ start_time).
            "Seconds.";
}

Висновок

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

Опубліковано: 29/03/11 @ 09:48
Розділ php

Рекомендуємо:

Перевірка стану сервера на онлайн
HTTP запити без CURL
Фріланс. Темна сторона вільного життя
SEO Toolbar для браузера Chrome від SEOmoz
Міфи про description (keywords) і html-коментарі