Скрытые возможности PHP? [закрыто]


174

Я знаю, что это звучит как вопрос для обсуждения, но позвольте мне объяснить, откуда я.

Вне колледжа я устроился на работу в магазин PHP. Я работал там полтора года и думал, что я узнал все, что можно было узнать о программировании.

Затем я получил работу в качестве единоличного внутреннего разработчика в крупной корпорации, где вся работа была на C #. В своей приверженности этой должности я начал читать тонну блогов и книг и быстро понял, как неправильно я думал, что знаю все. Я узнал о модульном тестировании, внедрении зависимостей и шаблонах декораторов, принципе проектирования слабой связи, обсуждении композиции по наследованию и так далее, и тому подобное - я все еще очень сильно поглощаю все это. Излишне говорить, что мой стиль программирования полностью изменился за последний год.

Теперь я ловлю себя на том, что беру проект php, занимающийся кодированием для запуска друга, и я чувствую себя полностью ограниченным в отличие от программирования на C #. Меня действительно беспокоит, что все переменные в области видимости класса должны быть указаны путем добавления '$ this->'. Меня раздражает, что ни одна из IDE, которые я пробовал, не имеет очень хорошего интеллекта и что мои методы модульных тестов SimpleTest должны начинаться со слова «test». Это сводит меня с ума, что динамическая типизация мешает мне неявно указывать, какой тип параметра ожидает метод, и что вам нужно написать оператор switch для выполнения перегрузок метода. Я не могу смириться с тем, что вы не можете иметь вложенные пространства имен и должны использовать оператор :: для вызова конструктора базового класса.

Сейчас я не собираюсь начинать дебаты по PHP против C #, я хочу сказать, что я уверен, что есть некоторые функции PHP, о которых я либо не знаю, либо знаю, но не могу их использовать должным образом. Я нахожусь в своей вселенной C # и испытываю проблемы с видением за пределами стеклянной чаши.

Итак, я спрашиваю, какие ваши любимые функции PHP? Что вы можете сделать в этом, чего вы не можете или более сложны в языках .Net?


Сломанная ОО парадигма? Для меня это худшая «скрытая» особенность, которую вы обнаружите.
knoopx

Эти темы довольно забавные ... Потому что для команды, в которой я работаю со "скрытой функцией", это кодовая фраза, означающая "ошибка". И вы знаете, что ... Иногда обнаружение скрытой функции не обязательно является хорошей вещью ...
Ганеш Шанкар

@ Ганеша ошибка одного человека - это скрытая особенность другого человека ...
Xeoncross

Ответы:


328

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


60
Я согласен. Возможность набирать www.php.net/function_name и получать ссылки большую часть времени - это здорово.
Аллен Лалонд

1
Это отличная особенность PHP, но я бы не стал называть это скрытым ... Если вы когда-нибудь гуглили параметры метода и т. Д., Вы оказались бы на php.net.
Джон Бубриски

27
Я тоже согласен. Самая большая вещь о руководстве - комментарии пользователя. Я редко видел, чтобы другие документы имели такие. Они могут содержать настоящие драгоценные камни. Единственным недостатком является то, что ИМХО они обрезали немного раньше времени.
Сандер Марешал

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

3
Не согласен. Единственная причина, по которой документация «хорошая», заключается в том, что некоторые комментарии пользователей закрывают все дыры в официальных заметках.
Роб Ховард

179

Массивы . Судя по ответам на этот вопрос, я не думаю, что люди полностью понимают, насколько просты и полезны массивы в PHP. Массивы PHP действуют как списки, карты, стеки и общие структуры данных одновременно. Массивы реализованы в языковом ядре и используются повсеместно, что приводит к хорошей локализации кэша ЦП. И 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

Обработчики потоков позволяют расширять «файловую систему» ​​с помощью логики, которую, насколько я знаю, довольно трудно сделать в большинстве других языков.

Например, с помощью обработчика потока 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, но должно ли это работать так?
Анти Вееранна

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

13
Если вы работаете с Amazon S3, ознакомьтесь с Zend_Amazon_S3, который предоставляет потоковый интерфейс для URL-адресов, таких как 's3: // {bucket-name} / path'.
Давидтбернал

Я использовал это, чтобы создать простой 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()велика в рамках с картой domain.com/controller/method/
Алекс

7
Магические методы также медленны, как ад. Используйте их осторожно.
Алекс Вайнштейн

95

Стандартный класс аккуратный контейнер. Я узнал об этом только недавно.

Вместо использования массива для хранения нескольких атрибутов

$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
"person [name] is $ person [age] years" также будет работать ... без кавычек, без скобок :)
majelbstoat

16
$ string = sprintf ("% s -% d лет.", $ person ['name'], $ person ['age']);
Даниэль Слооф

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

30
@majelbstoat: удаление кавычек замедлит работу сценария, потому что интерпретатор PHP будет проверять, были ли установлены name и age с помощью define (...). Это также плохая практика, учитывая, что было бы возможно полностью перевернуть ключи, к которым осуществляется доступ в каждом случае: define ('age', 'name'); DEFINE ( 'имя', 'возраст');
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.
Талви Вати

Это удобно для настройки быстрого и грязного файла конфигурации.
Франк Фармер

Почему вы возвращаете этот массив? Если включаемый файл содержит массив, его можно сразу же использовать при включении.
Фабрика

5
@fabrik, потому что это будет глобальная переменная и доступная во всей основной области видимости. Это довольно неприятно, это намного лучше.
Микулаш Дите

я работал над проектом в среде Yii, и у этого проекта есть файл конфигурации, в котором массив был возвращен так, теперь я понимаю, почему файл был таким.
Симер Твилио Торонто разработчик

83

Вы можете воспользоваться тем, что orоператор имеет более низкий приоритет, чем =сделать это:

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

Если значение первого назначения оценивается как true, второе назначение игнорируется. Другой пример:

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

7
Я не совсем уверен в этом, я думаю; даже если он не склонен к ошибкам, он нелогичен и сам по себе может вызывать ошибки.
Томасруттер

14
@ Пироги: если честно, один из следующих, довольно грязных кодов: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['page']: 1; // Преимущество этого в том, что подавление ошибок не требуется.
Рассерженная шлюха

3
если подумать, так как вы ищете целое число, которое вы могли бы использовать вместо: $ page = is_int ($ _ GET ['page'])? $ _GET ['page']: 1;
DisgruntledGoat

4
Стоит отметить, что код после orбудет выполняться, если код до orприводит к числовому значению 0. Так что семантически это может быть менее вероятно с чем-то вроде $_GET['page'], но, очевидно, могут возникнуть обстоятельства, и это хорошо, чтобы не упустить.
век

3
Также стоит отметить, что orоператор является более ранней версией ||оператора. Кроме того, +1, потому что это очень выразительно, и я часто забываю, что это возможно. Его следует использовать чаще, и абсолютно ясно, что он делает. Я не знаю, как «настоящие мужчины» кодируют, хотя, поэтому я не могу комментировать это.
век

80

__autoload()(класс-) файлы с помощью set_include_path().

В PHP5 теперь нет необходимости указывать длинные списки операторов include_once при выполнении приличного ООП.

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

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
Удобная функция, но единственное предостережение в том, что когда вы находите экземпляр данного класса, становится немного труднее выследить местоположение файла класса. Явное определение включений сверху дает вам конечный список участвующих классов и их точное местоположение.
Кори Дом

Это хорошая функция, но только для того, чтобы обойти ситуацию, когда код не был предварительно скомпилирован, поэтому он не знает, где будет находиться класс. Большим недостатком этого является то, что вы не можете иметь 2 класса с одинаковыми именами, даже если они находятся в разных пространствах имен.
Кибби

3
Пожалуйста, обратите внимание на PSR-0 от рабочей группы по стандартам PHP (с участием разработчиков ZF, Symfony, Doctrine, CakePHP, Solar и т. Д.) При реализации автозагрузки: groups.google.com/group/php-standards/web / psr-0-final-offer
Филипп Гербер

76

Лёгкость . Самая большая особенность заключается в том, как легко новым разработчикам сесть и написать «рабочие» сценарии и понять код.

Хуже всего то, как легко новым разработчикам сесть и написать «рабочие» скрипты и подумать, что они понимают код.

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

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


3
Определенно хороший комментарий. Python был моим первым языком, и он был потрясающим, но отсутствие проектов, которые я чувствовал способными понять, создавало барьер. С помощью PHP я могу найти что угодно в документации и выяснить это ... ресурсы, доступные в сети, просто потрясающие.
2010 года

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 (Спасибо @Ross & @Joshi Spawnbrood!). T


111
переменные переменные фактически делают код менее читаемым и более подверженным ошибкам.
Эльзо Валуги

8
И люди действительно этим пользуются? Человек я бы не хотел читать эти источники.
Гэри Уиллоуби

27
Переменные являются одной из худших функций, которые предлагает PHP.
Давидтбернал

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.
Алекс

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, вам нужно включить gazillion jar-файлы, а затем написать много стандартного кода.
Кимбл

16
«Таким способом вы даже можете включать () или требовать () кодовые файлы». Конечно, включить () файл на сервере, который вы не контролируете, - ужасная, ужасная идея.
Фрэнк Фармер

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

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

63

strtr ()

Это очень быстро, так сильно, что вы будете поражены. Внутренне он, вероятно, использует некоторую сумасшедшую структуру типа b-дерева, чтобы упорядочить ваши совпадения по их общим префиксам. Я использую его с более чем 200 строк поиска и замены, и он все еще проходит через 1 МБ менее чем за 100 мс. Для всех, кроме тривиально небольших строк, strtr () даже значительно быстрее, чем strtolower (), делает то же самое, даже принимая во внимание набор символов. Вероятно, вы могли бы написать весь анализатор, используя последовательные вызовы strtr, и это было бы быстрее, чем обычное сопоставление с регулярным выражением, выяснить тип токена, вывести то или иное, следующий тип регулярных выражений.

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


1
Вероятно, это быстрее, потому что он выполняет замену одного символа.
staticsan

10
strtr () не просто выполняет односимвольные замены. Он может заменить подстроки произвольной длины на другие подстроки произвольной длины, и это все еще кажется очень быстрым.
Томасруттер

1
Вы упомянули, что это было быстрее, чем strtolower в некоторых случаях, вы можете это доказать? Я сделал небольшой тест и обнаружил, что это неверно.
Pixel Developer

1
Я обнаружил, что на маленьких строках, скажем, 80 символов, это было медленнее, чем strtolower, а на больших строках, скажем, 1 МБ, это было быстрее. Скорее всего, каждый раз, когда он вызывается, возникают накладные расходы определенного типа. Я просто использовал strtr ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); Струна, над которой я работал, была типичным английским текстом («Быстрая коричневая лиса», такого рода вещи).
Томасруттер

Я только что прочитал этот пост, а затем провел поиск в 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
Я собирался рассердиться на вас за то, что вы предположили, что extract () каким-либо образом была хорошей особенностью. Но я думаю, что его использование довольно удобно. Я полагаю, это был один раз, когда я видел это, когда это хорошая идея!
Томасруттер

5
Функция extract () упрощает создание собственной чрезвычайно легкой системы шаблонов. +1
Дина

14
Его обратная функция compact () также хороша: $ a = 1; $ b = 2; компактный («а», «б»); // == массив ('a' => $ a, 'b' => $ b)
Анника Бэкстрем

2
Да, это, вероятно, единственное действительно хорошее использование extract ().
staticsan

4
В этом случае я бы предложил не использовать общие слова в качестве имен аргументов функции, поскольку $ context, из которого вы извлекаете (), может содержать значения в индексах 'as_string' или 'template_name'. Использование EXTR_SKIP допустимо, но только перемещает проблему в другое место (то есть, если шаблон ожидает $ as_string, он получит неправильное значение для него.)
Михал Татаринович

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 ($ array as $ 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 чиста и хорошо настроена).
dcousineau

4
На данный момент, но вы должны сделать переход только один раз, в то время как вам придется покупать новые лицензии рано или поздно ...
e-sat

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(...)которые вы бы вызывали более одного раза во время загрузки страницы.

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


7
Просто скопированная функция из C / C ++
GetFree

2
@ GetFree Не думаю, что кто-то будет отрицать, что почти весь PHP был скопирован с C, C ++, Perl и т. Д.
Фрэнк Фармер,

1
Копирование - лучшее, что можно сделать.
NikiC

1
Плохой PHP. Это всегда копирование функций от других. Вместо этого следует написать все с нуля! (В случае малейшей возможности того, чтобы это восприняли всерьез: я шучу)
Халил Эзгюр

42

Одна приятная особенность PHP - это CLI . Это не так «рекламируется» в документации, но если вам нужны обычные скрипты / консольные приложения, использование cron + php cli очень быстро развивается!


Я должен действительно разобраться в этом, у меня есть несколько заданий cron, которые wget http://example.com...
извлекают

CLI также является отличным способом точной отладки, поскольку предупреждения / ошибки будут отображаться без необходимости изменять настройки отчетов об ошибках.
Glacials

40

Тогда "и печатать" трюк

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

Будет повторять бла, если $ flag равен true. НЕ РАБОТАЕТ С ЭХО.

Это очень удобно в шаблоне и заменить? : это не очень легко читать.


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

26
На самом деле это то же количество символов, что и <? Php if ($ flag) print "Blah"
слишком много php

3
Круглые скобки не так просто набрать, как «и», особенно на моей окровавленной французской клавиатуре ;-)
e-suv

7
@ все комментарии - это не о том, как быстро вы можете получить это! Речь идет о удобочитаемости и простоте использования для пользователей шаблонов, которые иногда даже не программисты.
Тор Валамо

6
Я бы прокомментировал, что оператор if () проще и удобнее для чтения. Мне, конечно, легче разобраться, чем, по сути, использовать побочный эффект оператора 'и' в PHP, где легко ошибиться (или, похоже, это ошибка, когда вы читаете код позже). Например, как уже говорилось, это не будет работать так, как вы хотите с «эхо». С if () нет таких ошибок.
Томасруттер

37

Вы можете использовать минус в именах переменных следующим образом:

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

Зачем это использовать? Понятия не имею: может быть, для модели CSS? Или какой-то странный JSON, который вам нужно вывести. Это странная особенность :)


2
Это работает с именами методов? Может быть полезно для структур , которые используют маршрутизатор , и я хочу domain.com/something-with-minuses/view/
Алекс

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

2
При этом использовании переменные PHP могут принимать любые символы, даже пробелы и переводы строк.
Новичок

Это было бы очень полезно при использовании в SimpleXML ... круто. Спасибо, что поделился.
КайлФаррис

34

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

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

2
HEREDOC - мой любимый способ создания и использования операторов SQL.
2010 года

11
Примечание: закрытие МНВ; не может быть отступом.
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
Вам не нужно использовать определенную константу в качестве значения по умолчанию. Следующее также совершенно верно: функция foot ($ param1, $ default = array ('key' => 'value'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Однако вы правы, отметив, что вы не можете использовать переменную в качестве аргумента по умолчанию.
dcousineau

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

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) { };
Алекс

Если у вас есть FireFox; просто введите PHP functionв адресной строке, он будет выполнять поиск Google «Мне повезет», и вы почти всегда попадете на нужную страницу документации php.
Kolky

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
2010 г.

@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."

Вы не можете вызывать функции внутри {} напрямую, как это, но вы можете использовать переменные-удерживающие-имя-функции и вызывать их! (* и * вы также можете использовать переменные переменные)


2
Пожалуйста, не злоупотребляйте троичным оператором сравнения; это приводит к запутыванию кода.
staticsan

Вот это да. Это может полностью повлиять на ваш список $ GLOBALS. Плохая практика Шутки в сторону.
Талви Вати

Есть ли еще запутанный PHP-конкурс?
Lotus Notes

Ну, трюк со свопом - впечатляюще и полезно, спасибо.
OZ_

1
${''} = 456;хахаха .... довольно издевательства.
Скурмедель

26

Манипуляция массивом.
Тонны инструментов для работы с массивами и манипулирования ими. Возможно, он не уникален для PHP, но я никогда не работал с языком, который делал это так просто.


как например? Мне кажется, что все функции неуклюже названы и расположены в глобальном пространстве имен. Кроме того, я не могу думать ни о чем, что не так просто на другом языке, за исключением, может быть, $ arr [] = $ newvalue для добавления значений - это круто
Джордж Мауэр

8
Ну, массив PHP - это структура данных, которую можно легко использовать в качестве стека, очереди, очереди, списка, хеш-таблицы и т. Д. Он действительно достаточно гибкий для большинства общих потребностей, не прибегая к чему-либо еще, кроме функций 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()но немного проще. Я обнаружил, что обычно это то, что я хочу. По сути, он берет все записи в RHS и заставляет их появиться в копии 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, очевидно, что вы имеете дело с массивами.
Сильвен

И того факта, что вы делаете, ... + array( ...недостаточно, чтобы указать на это? :-)
staticsan

Какая версия 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
}

ЯВА:

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 ("one cat", "cat")) {
OIS

17
@OIS цель его примера состояла в том, чтобы проиллюстрировать и сравнить ход быстрого совпадения с регулярным выражением, а не то, как найти строку «cat» в «one cat».
dcousineau

19
Java: if (Pattern.matches ("cat", "one cat")) {// сделать что-то} Хватит жаловаться на Java, если вы этого не знаете.
вискисьерра

3
+1 Вилли, как ты делаешь preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Выбрать ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); на Яве? Это находит комментарий во входном тексте, а затем вызывает функцию с соответствующими элементами, которая в этом случае $ this-> choose (...) решает, чем заменить совпадение, и возвращает результаты.
DeveloperChris

1
Regex - это довольно дурацкий PHP ... Я бы предпочел использовать Regex в стиле Perl или JavaScript, где //он встроен в язык.
cdmckay
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.