Скрытые особенности PHP?

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

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

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

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

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

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

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

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

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

Например, с обработчиком MS-Excel Stream вы можете создать файл 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); 

Магические методы – это методы, которые вызываются при вызове метода, который не существует, или назначает или не считывает свойство, которое не существует, между прочим.

 interface AllMagicMethods { // accessing undefined or invisible (eg private) properties public function __get($fieldName); public function __set($fieldName, $value); public function __isset($fieldName); public function __unset($fieldName); // calling undefined or invisible (eg 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 (eg with (string) $obj, echo $obj, strlen($obj), ...) public function __toString(); // calling the object like a function (eg $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 ).

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

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

 $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."; 

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

 // config.php return array( 'db' => array( 'host' => 'example.org', 'user' => 'usr', // ... ), // ... ); // index.php $config = include 'config.php'; echo $config['db']['host']; // example.org 

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

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

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

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

__autoload() (class-), поддерживаемые 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 будет автоматически включать необходимые файлы по требованию, сохраняя время разбора и память.

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

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

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

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

Переменные переменные и функции без сомнения!

 $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);

Очень очень хорошо. Кодирование Make с петлями и шаблонами очень легко, и это быстрее и больше под контролем, чем eval (Thanx @Ross & @Joshi Spawnbrood!). T

Вы можете использовать функции с неопределенным количеством аргументов, используя 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); ?> 

Мне нравятся удаленные файлы . Для веб-разработки этот вид функции исключительно полезен.

Нужно работать с содержимым веб-страницы? Просто

 $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() файлы кода удаленно таким образом.

strtr ()

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

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

Не так хорошо известна функция 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" .

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"; } 

Веб-пространство с поддержкой PHP обычно менее дорого, чем что-либо с (asp) .net. Вы можете назвать эту функцию 😉

static ключевое слово полезно вне точки зрения ООП. Вы можете быстро и легко реализовать «memoization» или кеширование функций с чем-то простым:

 <?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(...) может быть намного лучше в зависимости от контекста.

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

Затем «и распечатать» трюк

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

Будет эхом Blah, если флаг $ true. НЕ РАБОТАЕТ С ЭХО.

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

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

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

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

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

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

Вероятно, мало кто знает, что в качестве значений по умолчанию для параметров функции можно указать постоянные «переменные»:

 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" 

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

http://php.net/function

В прошлом месяце я видел функцию «диапазон» в некотором коде. Это одна из сотен функций, которые мне никогда не удавалось использовать, но оказалось очень полезным:

http://php.net/range

Этот url является псевдонимом для http://us2.php.net/manual/en/function.range.php . Эта простая идея, функция отображения и ключевые слова для URL-адресов является удивительной.

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

Быстрые комментарии блока

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

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

Мой список .. большинство из них больше подпадают под «скрытые функции», чем «любимые функции» (надеюсь!), И не все они полезны, но .. да.

 // 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'); 

You can nest ternary operators too, comes in handy sometimes.

 // 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. 

Right, I'll stop for now 🙂


Hmm, it's been a while..

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

So, just discovered you can pass any string as a method name IF you enclose it with curly brackets. You can't define any string as a method alas, but you can catch them with __call(), and process them further as needed. Hmmm….

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

Found this little gem in Reddit comments:

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

You can't call functions inside {} directly like this, but you can use variables-holding-the-function-name and call those! (*and* you can use variable variables on it, too)

Array manipulation.
Tons of tools for working with and manipulating arrays. It may not be unique to PHP, but I've never worked with a language that made it so easy.

I'm a bit like you, I've coded PHP for over 8 years. I had to take a .NET/C# course about a year ago and I really enjoyed the C# language (hated ASP.NET) but it made me a better PHP developer.

PHP as a language is pretty poor, but, I'm extremely quick with it and the LAMP stack is awesome. The end product far outweighs the sum of the parts.

That said, in answer to your question:

http://uk.php.net/SPL

I love the SPL , the collection class in C# was something that I liked as soon as I started with it. Now I can have my cake and eat it.

Андрей

I'm a little surprised no-one has mentioned it yet, but one of my favourite tricks with arrays is using the plus operator. It is a little bit like array_merge() but a little simpler. I've found it's usually what I want. In effect, it takes all the entries in the RHS and makes them appear in a copy of the LHS, overwriting as necessary (ie it's non-commutative). Very useful for starting with a "default" array and adding some real values all in one hit, whilst leaving default values in place for values not provided.

Code sample requested:

 // 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 ); 

Here's one, I like how setting default values on function parameters that aren't supplied is much easier:

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

Quick and dirty is the default.
The language is filled with useful shortcuts, This makes PHP the perfect candidate for (small) projects that have a short time-to-market. Not that clean PHP code is impossible, it just takes some extra effort and experience.

But I love PHP because it lets me express what I want without typing an essay.

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 } 

And yes, that includes not typing Int .