Приховані особливості PHP? [зачинено]


174

Я знаю, що це звучить як питання, що стосується точки зору, але дозвольте мені пояснити, звідки я берусь.

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

Тоді я влаштувався на роботу в магазин для внутрішньої розробки в значній корпорації, де вся робота була в C #. Своєю прихильністю до позиції я почав читати багато блогів і книг і швидко зрозумів, наскільки я помиляюся, думаючи, що все знаю. Я дізнався про тестування одиниць, нагнітання залежностей та декоративні зразки, принцип дизайну нещільного з’єднання, склад над дебатами про спадщину, і так далі, і далі - я все ще дуже поглинаю це все. Потрібно сказати, що мій стиль програмування повністю змінився за останній рік.

Тепер я вважаю, що я підбираю php-проект, який робить кодування для запуску друга, і я відчуваю себе повністю обмеженим, на відміну від програмування на C #. Мене дійсно турбує те, що всі змінні в межах класу повинні бути посилаються, додавши "$ this->". Мене дратує те, що жоден із IDE, які я намагався, не має дуже хорошого інтелігенції і що мої методи тестування модулів SimpleTest повинні починатися зі слова "тест". Мене зводить з розуму, що динамічне введення тексту не дозволяє чітко вказати, який тип параметра очікує метод, і що вам потрібно написати оператор переключення, щоб зробити перевантаження методу. Я не можу стверджувати, що ви не можете мати вкладені простори імен і доведеться використовувати оператор :: для виклику конструктора базового класу.

Тепер я не маю наміру починати дискусію PHP проти C #, а те, що я хочу сказати, це те, що я впевнений, що є деякі функції PHP, про які я або не знаю, або про них ще не вдається правильно використовувати. Я розміщений у своєму C # Всесвіті і маю проблеми побачити поза скляною мискою.

Тож я запитую, які ваші улюблені особливості PHP? Які речі ви можете зробити в цьому, що ви не можете або складніше в мовах .Net?


Порушена парадигма ОО? Для мене це найгірша «прихована» особливість, яку ти відкриєш.
knoopx

Ці нитки є кумедними ... Тому що для команди, з якою я працюю зі «прихованою особливістю», це кодова фраза, що означає «помилка». І ви знаєте, що ... Іноді виявити приховану функцію не обов’язково - це добре ...
Ганеш Шанкар,

@Ganesh помилка одного чоловіка - інша прихована особливість людини ...
Xeoncross

Відповіді:


328

Документація . Документація отримує мій голос. Я не стикався з більш ретельною документацією в Інтернеті щодо мови програмування - все інше, що я маю скласти разом з різних веб-сайтів і man pages.


60
Я згоден. Велика частина можливостей набрати www.php.net/function_name і отримати довідку.
Аллан Лалонде

1
Це відмінна особливість PHP, але я б насправді не називав це прихованим ... Якщо ви коли-небудь гуглили за параметрами методу тощо, ви опинитесь на php.net.
Джон Бубріскі

27
Я також згоден. Найбільше про посібник - це коментарі користувачів. Я рідко бачив, щоб інші документації мали такі. Вони можуть містити справжні самоцвіти. Єдиним недоліком є ​​те, що ІМХО вони занадто скоро підрізали.
Сандер Маречал

3
@Phoexo "трохи менше для читання" ??? Я ніколи не розумів і ніколи не зрозумію MSDN, в той час як документи PHP прості та зрозумілі.
lauriys

3
Не погоджуюсь. Єдина причина, що документація є "хорошою" - це те, що деякі коментарі користувачів закупорюють усі отвори в офіційних нотатках.
Роб Говард

179

Масиви . Судячи з відповідей на це питання, я не думаю, що люди цілком оцінюють те, наскільки легкі та корисні масиви в PHP. PHP-масиви діють як списки, карти, стеки та загальні структури даних одночасно. Масиви реалізовані в мовному ядрі і використовуються в усьому місці, що призводить до гарної локальності кешу CPU. Perl та Python використовують окремі мовні конструкції для списків та карт, що призводить до більшого копіювання та потенційного заплутування перетворень.


11
Елементи масиву PHP впорядковані.
user8134

117
Мій початковий перехід від PHP до C # майже вбив мене. У C # масиви - це просто проста структура зі статичним розміром та числовим індексом. У PHP масиви - це клейка стрічка Всесвіту!
Діна

4
Я також згоден. Граючи з Java для завдання Uni, я був приголомшений тим, наскільки вони жорсткі, зовсім не гнучкість. Дійсно змусив мене оцінити, наскільки хороші масиви PHP.
Крістіан

11
Я впевнений, що масиви php чудові, але 40 голосів за коментар, який збиває масиви C #? Якщо масив C # не відповідає потребі, існує багато варіантів. Колекції ArrayList і загальні - це дуже потужні. Існують численні типи колекцій для конкретних потреб. Єдиною фактичною перевагою php в цьому плані є те, що він не надає жодних варіантів, з яких програміст повинен прийняти рішення. Ви або використовуєте масив, або не маєте змінної, що підлягає індексуванню.
G-Wiz

24
З іншого боку, синтаксис для масивів повністю висмоктується. У багатьох мовах сценаріїв можна створити простий 2D масив таким чином: [[1, 2], [3, 4]]порівняйте це з PHP версії: array(array(1, 2), array(3, 4)).
Рене Саарсоо

167

Обробники потоків дозволяють розширити "FileSystem" логікою, що, наскільки я знаю, в більшості інших мов зробити досить складно.

Наприклад, за допомогою обробника потоку MS-Excel ви можете створити файл MS Excel наступним чином:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);

Я вважаю, що рамка KIO дозволяє вам це робити, але це доступно лише для настільних додатків на основі KDE.
MiffTheFox

21
ІМХО, що має правильний підхід до ОО, було б набагато розумнішим, ніж цей безлад з обробниками потоків. Так, це мило вміти читати / писати файли Excel, але чи має це працювати так?
Anti Veeranna

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

13
Якщо ви працюєте з Amazon S3, перегляньте Zend_Amazon_S3, який забезпечує інтерфейс потоку для URL-адрес, таких як 's3: // {bucket-name} / path'.
davidtbernal

Я використовував це для створення простого DSL для мого шару перегляду, просто прочитавши файл PHP, зробивши заміну рядків і передавши його через eval (). Наприклад, я зробив це таким чином, що я можу використовувати короткі теги всякий раз, коли мені захочеться робити @ @> someVar, щоб я мав доступ до даних рівня перегляду.
Джаспер Беккерс

131

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

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

Тут розробник C ++ може помітити, що PHP дозволяє перевантажувати деякі оператори, наприклад, ()або (string). Насправді PHP дозволяє перевантажувати ще більше, наприклад, []оператор ( ArrayAccess ), foreachмовна конструкція ( Iterator та IteratorAggregate ) та countфункція ( Countable ).


4
Як корисний приклад того, що можна досягти за допомогою магічних методів, перейдіть на сторінку phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom

6
Не погоджуюсь. Це набагато слабше, ніж подібні засоби у Smalltalk, Ruby & Python (і, мабуть, було скопійовано з одного з них)
finnw

34
Той факт, що PHP реалізує цю функціональність слабше, ніж інші мови, не робить її менш корисною для PHP.
Аллайн Лалонде

2
__call()чудово підходить для карток з доменом map.com/controller/method/
alex

7
Магічні методи також повільні, як пекло. Використовуйте їх обережно.
Алекс Вайнштейн

95

Стандартний клас акуратний контейнер. Про це я дізнався лише нещодавно.

Замість використання масиву для зберігання атрибутів serral

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

Можна використовувати стандартний клас

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

Це особливо корисно при доступі до цих змінних у рядку

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

43
"{$ person ['name']} працює {$ person ['age']} років" працює.
Корнель

27
"особа [ім'я] - $ людина [вік] років" також буде працювати ... Ні котирування, ні підтяжки :)
majelbstoat

16
$ string = sprintf ("% s -% d років.", $ person ['ім'я'], $ person ['вік']);
Даніель Слоуф

60
Поки ми на тему: (object) масив ("name" => 'bob', 'age' => 5)
Annika Backstrom

30
@majelbstoat: Виведення котирувань уповільнить сценарій, оскільки інтерпретатор PHP буде дивитись, чи встановлено 'name' та 'age' з define (...). Це також погана практика, враховуючи, що можна повністю перевернути клавіші, до яких можна отримати доступ у кожному випадку: define ('age', 'name'); визначити ('ім'я', 'вік');
brianreavis

90

Файли, що включають файли, можуть мати повернене значення , яке можна призначити змінній.

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

@Peter ДУЖЕ корисний для обробки помилок db- > localhost.
Талві Ватія

Це зручно для налаштування швидкого та брудного конфігураційного файлу.
Френк Фермер

Чому ви повертаєте цей масив? Якщо включений файл містить масив, він може бути використаний при включенні негайно.
fabrik

5
@fabrik, оскільки це буде глобальною змінною та доступною у всьому головному обсязі. Це зовсім неприємно, це так краще.
Mikulas Dite

Я працював над проектом в рамках Yii, і цей проект мав конфігураційний файл, в якому масив повертався так, тепер я розумію, чому файл був таким.
розробник Simer Twilio Toronto

83

Ви можете скористатися тим, що orоператор має нижчий пріоритет, ніж =це:

$page = (int) @$_GET['page'] 
  or $page = 1;

Якщо значення першого завдання оцінюється на true, друге призначення ігнорується. Ще один приклад:

$record = get_record($id) 
  or throw new Exception("...");

7
Я не зовсім переконаний у цьому, думаю; незважаючи на те, що, здається, не схильні до помилок, це контрінтуїтивно, і саме по собі це може сприяти помилкам.
thomasrutter

14
@Pies: один із способів - це наступний, досить брудний код, якщо чесно: $ page = isset ($ _ GET ['сторінка'])? (int) $ _ GET ['сторінка']: 1; // Перевагою цього немає придушення помилок.
НезадоволенняГотуйте

3
по-друге, з огляду на те, що ви шукаєте ціле число, яке ви могли б використовувати натомість: $ page = is_int ($ _ GET ['сторінка'])? $ _GET ['сторінка']: 1;
НезадоволенняГотуйте

4
Варто зауважити, що код після orбуде виконуватися, якщо код перед цим orпризведе до числового значення 0. Тож семантично це може бути менш ймовірним із чимось подібним $_GET['page'], але очевидно, що обставина може виникнути, і на це варто стежити.
безглазкість

3
Варто також зазначити, що orоператор - це версія нижнього прецеденту ||оператора. Також +1, оскільки це дуже виразно, і я часто забуваю, що це можливо. Його слід використовувати частіше, і абсолютно зрозуміло, що він робить. Я не знаю, як "справжні чоловіки" код, хоча, тому я не можу це коментувати.
безвічність

80

__autoload()(class-) файли за допомогою set_include_path().

У PHP5 тепер не потрібно вказувати довгі списки висловлювань "include_once", коли робите гідний OOP.

Просто визначте невеликий набір каталогів, в яких файли бібліотеки класів є чітко структурованими, і встановіть шлях автоматичного включення:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Тепер __autoload()рутина:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Тепер PHP автоматично включатиме необхідні файли на вимогу, що забезпечує економію часу та пам'яті.


Spl_autoload_register () краще використовувати?
alex

19
Звичайно! __autoload () - PHP4, але spl_autoload_register () є неруйнівним "ланцюжком ромашок" методів автозавантаження.
Віллем

3
Зручна функція, але один застереження - коли ви знайдете екземпляр даного класу, це ускладнює пошук місця розташування файлу класу. Явне визначення, що включає вгорі, дає вам обмежений перелік залучених класів та їх точне місцезнаходження.
Cory House

Це приємна особливість, але лише обійти ситуацію з тим, що код не був попередньо складений, тому він не знає, де буде клас. Великим недоліком цього є те, що ви не можете мати 2 класи з тим самим іменем, навіть якщо вони знаходяться в різних просторах імен.
Кіббі

3
Будь ласка, подивіться на PSR-0 рефералу робочої групи з питань стандартизації PHP (із розробниками ZF, Symfony, Doctrine, CakePHP, Solar тощо) при здійсненні автоматичного завантаження: groups.google.com/group/php-standards/web / psr-0-final-offer
Philippe Gerber

76

Легкість . Найбільшою особливістю є те, як легко розробникам сісти і написати "робочі" сценарії та зрозуміти код.

Найгірша особливість полягає в тому, як легко розробникам сісти і написати "робочі" сценарії та подумати, що вони розуміють код.

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

Я не буду обговорювати технічні речі, як багато хто раніше, але якщо ви дивитесь на PHP як на спільноту, а не на веб-мову, спільноту, яка чітко сприйняла вас, коли ви почали розвиватися, переваги справді говорять самі за себе.


3
Безумовно, хороший коментар. Python був моєю першою мовою, і це було приголомшливо, але відсутність проектів, які я відчував здатними зрозуміти, створив бар'єр. За допомогою PHP я можу знайти майже все на документації та зрозуміти це ... ресурси, наявні в Інтернеті, є дивовижними.
dscher

76

Змінні змінні та функції без сумніву!

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

Це ж поняття застосовується до параметрів об'єкта ($ some_object -> $ some_variable);

Дуже-дуже хороший. Зробити кодування за допомогою циклів і шаблонів дуже просто, і це швидше і під контролем, ніж eval (Thanx @Ross & @Joshi Spawnbrood!). T


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

8
І люди справді цим користуються? Людина, мені б не хотілося читати ці джерела.
Gary Willoughby

27
Змінні змінні - одна з найгірших особливостей, яку пропонує PHP.
davidtbernal

10
9 З 10-кратних змінних змінних краще замінити масиви, щоб у вас були всі дані в одному місці, ви можете перебирати їх і так далі. Тільки в деяких дуже конкретних обставинах вони можуть бути корисними.
Джаспер Беккерс

7
Не дозволяйте новачкам користуватися цією "функцією".
віскісієра

68

Ви можете використовувати функції з невизначеною кількістю аргументів, використовуючи func_get_args().

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>

1
Якраз збирався опублікувати це. Начебто властивість аргументів у функціях JS.
alex

67

Я люблю віддалені файли . Для веб-розробок така функція є надзвичайно корисною.

Потрібно працювати зі вмістом веб-сторінки? Простий

$fp = fopen('http://example.com');

і у вас є ручка файлу готова до запуску, як і будь-який інший звичайний файл.

А як щодо читання віддаленого файлу чи веб-сторінки безпосередньо в рядку?

$str = file_get_contents('http://example.com/file');

Корисність цього конкретного методу важко перебільшити.

Хочете проаналізувати віддалене зображення? Як щодо цього робити через FTP?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

Практично будь-яка функція PHP, яка працює з файлами, може працювати з віддаленим файлом. Ви можете навіть include()або require()кодувати файли віддалено таким чином.


2
Це так приємно! Для цього, наприклад, Java, вам потрібно включити файли jar-мільйонів gazillion і потім написати багато кодового коду.
Кімбл

16
"Ви навіть можете дистанційно включати () або вимагати () файли коду таким чином." Звичайно, включити () ing файл на сервері, яким ви не керуєте, це жахлива, жахлива ідея.
Френк Фермер

4
@Frank - так, ну, можна було б припустити , що ви будете в тому числі код з сервера , який ви зробили контроль.
зомбат

1
До речі, віддалене включення файлів є поширеною проблемою безпеки PHP: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Френк Фермер,

63

strtr ()

Це надзвичайно швидко, настільки, що ви були б вражені. Внутрішньо він, ймовірно, використовує якусь божевільну структуру типу b-tree, щоб упорядкувати свої поєднання за їх загальними приставками. Я використовую його з більш ніж 200 рядками пошуку та заміни, і він все ще проходить через 1 Мб менш ніж за 100 мс. Для всіх, крім тривіально малих рядків, strtr () навіть значно швидше, ніж strtolower (), роблячи абсолютно те саме, навіть враховуючи встановлені символи. Можливо, ви могли б написати цілий аналізатор, використовуючи послідовні дзвінки strtr, і це було б швидше, ніж звичайне збіг регулярних виразів, з'ясувати тип жетону, вивести той чи інший, наступний вид регулярного виразу.

Я писав нормалізатор тексту для розбиття тексту на слова, зменшення рядків, видалення розділових знаків тощо, і strtr був моїм швейцарським армійським ножем, він бив штани з регулярних виразів або навіть str_replace ().


1
Це, мабуть, швидше, тому що він робить заміну одного символу.
статик

10
strtr () не просто виконує заміну одного символу. Він може замінити підрядки довільної довжини іншими підрядками довільної довжини, і це все ще здається дуже швидким.
thomasrutter

1
Ви згадали, що в деяких випадках це було швидше, ніж strtolower, чи можете ви це довести? Я зробив невеликий орієнтир і виявив, що він помилковий.
Розробник Pixel

1
Я виявив, що на малих рядках скажімо 80 символів це повільніше, ніж у strtolower, а на великих струнах скажімо 1 Мб - це швидше. Напевно, є якісь накладні витрати з кожним викликом кожного разу. Я просто використовував strtr ($ this-> рядок, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); Рядок, над яким я працював, був типовим англійським текстом ("Швидка коричнева лисиця", така штука).
thomasrutter

Я щойно прочитав цю публікацію, а потім здійснив пошук у Google і знайшов: simplemachines.org/community/index.php?topic=175031.0 Будь-яка ідея, який з них правильний?
Фліппер

61

Однією не дуже відомою особливістю PHP є extract()функція, яка розпаковує асоціативний масив у локальний простір імен. Це, ймовірно, існує для автоглобального припинення, але дуже корисно для створення шаблонів:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Тепер ви можете використовувати render_template('index.html', array('foo' => 'bar'))і лише $fooзі значенням, що "bar"з’являється в шаблоні.


15
Я збирався розсердитися на вас за те, що пропонувати витяг () будь-яким чином було гарною особливістю. Але я здогадуюсь, що використовувати його досить зручно. Я гадаю, що це колись я бачив, як його використовували там, де це гарна ідея!
thomasrutter

5
extract () робить простою прокат вашої власної надзвичайно легкої системи шаблонів. +1
Діна

14
Зворотна, компактна (), добре також: $ a = 1; $ b = 2; компактний ('a', 'b'); // == масив ('a' => $ a, 'b' => $ b)
Annika Backstrom

2
Так, це, мабуть, єдине дійсно хороше використання екстракту ().
staticsan

4
Я б запропонував не використовувати в цьому випадку загальні слова як назви аргументів функції, оскільки контекст $, з якого ви виймаєте (), може містити значення в індексах 'as_string' або 'template_name'. Використання EXTR_SKIP прийнятне, але лише переміщує проблему в інше місце (тобто, якщо шаблон очікує $ as_string, він отримає для нього неправильне значення.)
Michał Tatarynowicz

52

Range () сам по собі не прихований, але я все ще бачу багато людей, які повторюють:

for ($i=0; $i < $x; $i++) { 
    // code...
}

коли вони можуть використовувати:

foreach (range(0, 12) as $number) {
    // ...
}

І ви можете робити прості речі на кшталт

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}

3
ви можете робити foreach ($ масив як $ key => $ value) {}, що ще простіше.
SilentGhost

15
Це може бути мікрооптимізація, але варто зауважити, що час і час є набагато швидшими та менш пам'ятними, ніж foreach.
JAL

3
Спробуйте спробувати Python. Це так само просто, як "для i в діапазоні (12)", або ви можете використовувати більш ефективний xrange.
Ponkadoodle

2
@SilentGhost: для початку вам знадобиться масив, що не завжди так. @Newbie: детальніше будь ласка?
Алек

1
@flexxy, напевно, це НЕ. Врахуйте це: phpbench.com прокрутіть вниз до Read Loop.
Бадді

44

Веб-простір з підтримкою PHP зазвичай дешевший, ніж щось із (asp) .net. Ви могли б назвати , що особливість ;-)


3
Також набагато дешевше налаштувати декілька серверів, якщо вам не доведеться платити за Windows Server на кожному.
MiffTheFox

4
Єдине місце, де я знаю, де Windows є рентабельним, - це університет, який отримує знижки STEEEEP на серверне програмне забезпечення настільки ж, наскільки моїй кафедрі дешевше придбати 100 копій вікон, ніж це навчити наших адміністраторів на Linux (що частково мене сумно, але їх налаштування Windows чиста і добре налаштована).
dcosineau

4
Поки що, але вам потрібно зробити перемикання лише один раз, тоді як вам доведеться рано чи пізно купувати нові ліцензії ...
e-satis

42

staticКлючове слово корисно за межами ООП точки зору. Ви можете швидко та легко реалізувати "запам'ятовування" або кешувати функції чимось простим, як:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

staticКлючове слово створює змінну , яка зберігається тільки в рамках цієї функції минулому виконання. Ця методика відмінно підходить для функцій, які потрапляють на базу даних, get_all_books_by_id(...)або get_all_categories(...)які ви б дзвонили не раз під час завантаження сторінки.

Caveat: Переконайтеся, що ви знайшли найкращий спосіб зробити ключ для вашого хешу, майже за будь-яких обставин md5(...)вищевказане НЕ є гарним рішенням (питання швидкості та довжини вихідних даних), я використовував це для ілюстративних цілей. sprintf('%u', crc32(...))або spl_object_hash(...)може бути набагато краще, залежно від контексту.


7
Тільки скопійована функція з C / C ++
GetFree

2
@GetFree Я не думаю, що хтось заперечує, що майже весь PHP був скопійований з C, C ++, Perl тощо.
Френк Фармер,

1
Копіювання - найкраще, що можна зробити.
NikiC

1
Поганий PHP. Це завжди копіювання функцій від інших. Натомість слід писати все з нуля! (У разі найменшої можливості це сприймати серйозно: я жартую)
Halil Özgür

42

Однією приємною особливістю PHP є CLI . Це не так "просувається" в документації, але якщо вам потрібні звичайні скрипти / консольні програми, використання cron + php cli дуже швидко розвивається!


Мені справді варто розібратися в цьому, у мене є декілька завдань Cron, які отримують скрипт PHPwget http://example.com...
DisgruntledGoat

CLI - це також чудовий спосіб усунення налагодження, оскільки відображатимуться попередження / помилки, без того, щоб вам було потрібно змінювати налаштування звітування про помилки.
Glacials

40

Потім трюк «та друкуй»

<?php $flag and print "Blah" ?>

Буде лунати, якщо прапор $ правда. НЕ ПРАЦЮЄ З ЕХО.

Це дуже зручно в шаблоні і замінити? : це не дуже легко читати.


24
Я сам вважаю потрійний оператор набагато очевиднішим, ніж використання короткого замикання оцінки логічного і.
Vicent Marti

26
Насправді це така ж кількість символів, як <? Php якщо ($ flag) надрукувати "Blah"
занадто багато php

3
Парентез не такі прості, як "і", особливо на моїй кривавій французькій клавіатурі ;-)
e-satis

7
@all коментарі - це не про те, як коротко ви можете його отримати! Йдеться про читабельність та простоту використання для шаблонів, які іноді навіть не є програмістами.
Tor Valamo

6
Я б прокоментував, що твердження if () простіше і читабельніше. Мені, звичайно, простіше обійти голову, ніж по суті використовувати побічний ефект оператора 'і' в PHP, де легко помилитися (або схоже, що це помилка, коли читаєш код пізніше). Наприклад, як зазначено, це не працюватиме так, як ви хочете, за допомогою "відлуння". З if () таких немає таких.
thomasrutter

37

Ви можете використовувати мінус символи в таких назвах змінних :

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

Навіщо його використовувати? Не маю ідеї: можливо, для моделі CSS? Або якийсь дивний JSON, який вам потрібно вивести. Це дивна особливість :)


2
Це працює з назвами методів? Може бути корисним для фреймворків, які використовують маршрутизатор, і я хочу domain.com/something-with-minuses/view/
alex

6
Фігурні дужки дозволяють отримати доступ до власних об'єктів об'єктів, які мають тире, крапки та інші не буквено-цифрові об'єкти. Однією з причин використовувати його є при роботі з xml, де імена об'єктів можуть бути розставлені крапками, як у NITF / NewsML <body.content>. Якщо ви використовуєте SimpleXML, ви отримаєте доступ до нього так $item->DataContent->body->{'body.content'}.
Джессі Кочіс

2
Змінні PHP можуть приймати будь-які символи при використанні таким чином, навіть пробіли та нові рядки.
Новачок

Це було б дуже корисно при використанні в SimpleXML ... приголомшливо. Дякую, що поділились.
KyleFarris

34

Синтаксис HEREDOC - моя улюблена прихована функція. Завжди важко знайти, оскільки ви не можете Google за <<<, але це перешкоджає вам уникати великих шматочків HTML і все одно дозволяє вам скидати змінні в потік.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

2
HEREDOC - це мій улюблений спосіб створення та використання операторів SQL.
bdl

11
Примітка: закриття EOM; не можна відступити.
micahwittman

Добре, але безглуздо, якщо ви використовуєте шаблони. Плюс це стає на шляху належного відступу.
Манос Ділаверакіс

7
Шановний боже, це найпотворніший фрагмент коду, який я коли-небудь бачив. Якщо ви використовуєте HEREDOC, то ви не відокремили презентацію від логіки.
Lotus Notes

@Byron: Вам не доведеться використовувати його для презентації, його можна використовувати для будь-якого рядка. Дивіться коментар від bdl.
Том Пажурек

34

Напевно, мало хто знає, що для параметрів функції можна вказати постійні "змінні" як значення за замовчуванням:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Рядки можна використовувати так, ніби вони були масивами :

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"

3
Цей останній витончений. Хоча я поняття не маю, коли це було б краще, ніж якийсь інший метод видалення персонажа. +1, тим не менше
Джордж Мауер

3
Це, мабуть, ефективніше, ніж викликати функцію для цього. Струни, як правило, постійно зберігаються в пам'яті, тому дохід до $ str [4] є тривіальним. Збереження рядків як масивів символів є загальним для більшості мов, що походять від C.
sjobe

1
Не потрібно використовувати визначену константу як значення за замовчуванням. Наступне також цілком справедливо: функція фут ($ param1, $ default = array ('ключ' => 'значення'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Однак ви вірно зазначили, що не можете використовувати змінну як аргумент за замовчуванням.
dcosineau

@dcoseineau Ваш приклад цілком справедливий, оскільки масив () - це не функція, а мовна конструкція. Виклики функцій не дозволяються як значення за замовчуванням для аргументів.
Джамол

4
Будьте обережні, поводьтесь з рядками як з масивами, якщо у вас є багатобайтові рядки (іноземні мови тощо)
philfreo

33

Найбільш корисна річ щодо PHP-коду - це те, що якщо я не дуже розумію функцію, я бачу, я можу знайти її за допомогою браузера та набравши:

http://php.net/function

Минулого місяця я бачив функцію "діапазон" у якомусь коді. Це одна із сотень функцій, які мені вдалося ніколи не використовувати, але виявилася дуже корисною:

http://php.net/range

Цей URL - псевдонім для http://us2.php.net/manual/en/function.range.php . Ця проста ідея щодо відображення функцій та ключових слів для URL-адрес є приголомшливою.

Я хочу, щоб інші мови, рамки, бази даних, операційні системи мали настільки простий механізм пошуку документації.


5
range()може бути корисним дляforeach( range(1, 10) as $i) { };
alex

Якщо у вас є FireFox; просто введіть PHP functionв адресному рядку, він здійснить пошук Google "Мені пощастило", і ви майже завжди опиняєтесь на правій сторінці документації на PHP.
Колькі

30

Швидкий блокування коментарів

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

Ці коментарі дозволяють перемикатися, якщо кодовий блок коментується одним символом.


14
Це насправді не характерно для PHP. Це працює будь-якою мовою, яка підтримує // ...коментарі до рядків та /* ... */блокує коментарі.
Джордан Райан Мур

будь-які утиліти для очищення коду ненавидять вас за використання цього ...;)
Talvi Watia

3
Я також використовував /** /до і /**/після. Ви можете переключити блок, видаливши та додавши пробіл у першому. Це має додаткову перевагу роботи з CSS (та іншими мовами, які не підтримують // ... коментарі).
kingjeffrey

FWIW, посилання на оригінальну статтю aleembawany.com/2009/01/27/lazy-block-comment-trick
aleemb

@aleemb, утримуйтесь від будь-яких подальших змін до цього питання.
Sam152

29

Мій список .. Більшість з них більше підпадає під "приховані функції", ніж "улюблені функції" (сподіваюся!), І не всі вони корисні, але .. так.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

Ви також можете вкладати потрійних операторів, що іноді стане в нагоді.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Правильно, я зараз зупинюсь :-)


Хм, минув час ..

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

Отже, щойно виявивши, ви можете передавати будь-яку рядок як ім'я методу, якщо ви додаєте її до фігурних дужок. Ви не можете визначити жоден рядок як метод на жаль, але ви можете спіймати їх за допомогою __call () та обробити їх далі за потребою. Хммм….

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

Знайдено цю маленьку дорогоцінну каменю в коментарях Reddit:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

Ви не можете викликати функції всередині {} прямо так, але ви можете використовувати змінні-hold-the-function-name і викликати їх! (* і * ви також можете використовувати змінні змінні)


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

Ого. Це могло б повністю заповнити ваш список $ GLOBALS. Погана практика. Серйозно.
Талві Ватія

Чи є ще заплутаний конкурс PHP?
Lotus Notes

Ну, трюк із свопом - вражаючий та корисний, дякую.
OZ_

1
${''} = 456;ха-ха .... цілком зловживання.
Skurmedel

26

Маніпулювання масивом.
Тон інструментів для роботи з масивами та управління ними. Це може бути не унікальним для PHP, але я ніколи не працював з мовою, яка зробила це так легко.


як, наприклад, що? Мені здається, всі функції незручно названі та розміщені у глобальному просторі імен. Плюс я не можу придумати щось інше настільки просто, за винятком, можливо, $ arr [] = $ newvalue для додавання значень - це круто
Джордж Мауер

8
Ну, масив PHP - це структура даних, яку можна легко використовувати як стек, черга, deque, список, хешбел тощо. Це досить гнучка дійсність для найбільш загальних потреб, не вдаючись до іншого, крім функцій array_ *.
Каміло Діаз Репка

6
Python робить масиви (як списки та кортежі) набагато краще, ніж це PHP.
занадто багато php

26

Я трохи схожий на вас, кодую PHP вже більше 8 років. Мені довелося пройти курс .NET / C # близько року тому, і мені дуже сподобалася мова C # (ненавидів ASP.NET), але це зробило мене кращим розробником PHP.

PHP як мова є досить бідним, але, я надзвичайно швидкий з цим, і стек LAMP є приголомшливим. Кінцевий продукт значно переважає суму частин.

Це сказав, відповідаючи на ваше запитання:

http://uk.php.net/SPL

Я люблю SPL , колекційний клас на C # був чимось, що мені сподобалось, як тільки я почав з нього. Тепер я можу мати свій торт і з'їсти його.

Андрій


24

Я трохи здивований, поки ніхто про це не згадував, але одним з моїх улюблених трюків з масивами є використання оператора плюс. Це трохи схоже, array_merge()але трохи простіше. Я знайшов, що це зазвичай те, що я хочу. По суті, він приймає всі записи в РЗС і змушує їх відображатися в копії LHS, переписуючи за необхідності (тобто це некомутативно). Дуже корисно починати з масиву "за замовчуванням" та додавати деякі реальні значення все в один хіт, залишаючи при цьому значення за замовчуванням для значень, які не надаються.

Запрошений зразок коду:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );

$defaultsповинно бути$control_defaults
diEcho

3
Я думаю, що це не так зрозуміло, як array_merge, коли у вас є багато коду для підтримки. Принаймні, коли ви використовуєте функцію array_merge, видно, що ви маєте справу з масивами.
Sylvain

І того факту, який ви робите ... + array( ..., недостатньо, щоб це вказувати? :-)
статисман

Яка версія PHP вам потрібна для цього?
Lotus Notes

Це відмінна особливість, і слід зазначити, що масив на "правій" стороні "+" не буде перезаписувати наявні ключі масиву на "ліву" сторону "+".
Віл Мур III,

21

Ось один, мені подобається, як налаштувати значення за замовчуванням для функціональних параметрів , які не постачаються, набагато простіше:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

4
Як не дивно, я побачив цю "приховану функцію" в Google Reader минулого тижня. Я не розумію, що в ньому приховано - це основний синтаксис. Спробуйте, наприклад, ($ var = true).
Росс

8
Простіше, ніж що? Більшість мов мають цю особливість.
Крістіан Давен

10
Легше, ніж на C # (а я думаю, що C ++ і Java)
Джордж Мауер

8
C ++ підтримує значення параметрів за замовчуванням.
sjobe

2
c # взагалі не підтримує значення за замовчуванням. ви повинні написати перевантажену функцію і завжди оголошувати значення, яке є просто громіздким
DeveloperChris

21

Швидке і брудне - це за замовчуванням.
Мова наповнена корисними ярликами. Це робить PHP ідеальним кандидатом для (малих) проектів, які мають короткий час на ринок. Не те, щоб очистити PHP-код неможливо, це просто потребує додаткових зусиль та досвіду.

Але я люблю PHP, тому що це дозволяє мені висловлювати те, що я хочу, не набираючи есе.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

І так, це включає не введення Int .


4
замість цього слід використовувати strpos: if (false! == strpos ("одна кішка", "кішка")) {
OIS

17
@OIS мета його прикладу полягала в тому, щоб проілюструвати та порівняти біг швидкого збігу регулярних виразів, а не як знайти рядок "cat" в "one cat".
dcosineau

19
Java: якщо (Pattern.matches ("кішка", "одна кішка")) {// зробіть щось} Перестаньте скаржитися на Java, якщо ви цього не знаєте.
віскісієра

3
+1 Віллі, як ти робиш preg_replace ('/ ([<<]! \ S *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Виберіть ('\\ 1', '\\ 2', '\\ 3', \ $ дані) ", $ текст); на Java? Це знаходить коментар у вхідному тексті, а потім викликає функцію з відповідними елементами, яка в цьому випадку $ this-> select (...) вирішує, чим замінити збіг, і повертає результати.
DeveloperChris

1
Regex - це PHP досить хитро ... Я б швидше мав Perl або JavaScript у стилі Regex, де //вбудований у мову.
cdmckay
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.