О сайтах и не о сайтах

Теперь и в tg!

tg

Переехал с твиттера на t.me/tulvit_blog, если что.

Двойные и одинарные кавычки в php

Я сторонник красивого и оптимизированного кода, хоть и не всегда у меня получается следовать всем правилам «хорошего тона» в программировании.

Сейчас же речь пойдет о правильном использовании двойных и одинарных кавычек в php. Перед тем, как начать писать пост, я бегло просмотрел имеющиеся у меня книги по php, и, что странно, ни в одной не увидел правильного использования кавычек. Почему – для меня загадка. Обвинять авторов в дилетантстве нет ни малейшей возможности, книги далеко не для «чайников». Может быть просто не хотели акцентировать на этом внимание, дескать кому надо, тот сам разберется.

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

Следовательно, если нам надо вывести текст «как есть», то используем одинарные кавычки. Если необходимо подставить вместо переменной ее значение – двойные (если переменная только одна, то кавычки можно и вовсе опустить). Часто можно встретить такой код:

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

Рассмотрим тривиальную задачу вывода переменной в составе текста, в том числе и с использованием html кода.

$date;
echo "Сегодняшняя дата: $date";
?>

Все выводится хорошо, текст и выделенная жирным дата, которая подставляется вместо переменной. Но необходимо помнить две вещи. Первое, это особенность интерпретатора: конкатенация строк происходим намного быстрее и требует меньше ресурсов, нежели синтаксический анализ строк. И второе - не стоит забывать про парадигму программирования «разделяй и властвуй». Не надо мешать все в одно, гораздо правильнее будет разделить текст на две части – требующую и не требующую парсинга интерпретатором. Таким образом, пример выше стоит записать так:

$date;
echo 'Сегодняшняя дата: '.$date.'';
?>

Естественно, следовать этому правилу (заключать все, что не требует парсинга, в одинарные кавычки) надо не только при выводе текста, но и при присвоении значений строковым переменным:

Или, например, при использовании строк при передаче аргументов функции:

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

Комментарии

Спрашивается, а нафига вообще было реализовано в PHP возможность вывода строк в двойных кавычках? только лишь для сокращения кода?:)

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

Учту, запомню.

Да... не знал, спасибо за статью :)

Статья хорошая, хоть буду теперь знать. А то кого не спросишь - тот прям гений, а толком объяснить ничего не может.

Спасибо, помогло :)

А я никак не мог понять как вывести текст "как есть" в хтмл страницу из пхп-файла, спасибо огромное

Да, а если тада-тада выводить в цикле через printf строки и чтобы они были ссылками? Ставим одинарные кавычки. И что? Валидатор ругается! validator.3w.org . Как исправить то?

Не совсем понял, что и как надо выводить и на что ругается валидатор=)
При такой записи
printf('>a href="http://%s/"<%s>/a<', 'site.com', 'anchor');
ошибок быть не должно. Или это я совсем не о том?
(Знаки ">" и "<" в примере развернуты в другую сторону, а то парсер код в ссылку превращает.)

Вот у меня такая проблемма у меня цикл в нем printf Так мне надо чтобы FireFox 3.6 не превращал мои ссылки в текст.?

У меня вопрос может не по адресу. Начал изучать php, на стадии вводного урока и вдруг обнаружил, что у меня в блокноте кавычки как то странно появляются. Первую невидно, а после второго щелчка сразу две. Может это в каких то настройках.

Единственное, что приходит в голову - у вас навороченный блокнот с включенными по умолчанию функциями автоформатирования и так далее (вроде в Windows 7 от доброго старого блокнота XP уже ничего не осталось, но утверждать не буду, в Windows я редкий гость, Linux наше все).

Что могу посоветовать - откажитесь от блокнота в пользу легкой IDE, не пожалеете. Лучший вариант - Geany

У меня простой блокнот, проще некуда от Windows XP, я им пользуюсь потому что он мало места на экране занимает, ну если текст с экрана переписывать. И раньше всё было нормально. А теперь и в блокноте и в Wordpad в английской раскладке:
- кавычка как бы есть, но её не видно, появляется только когда ввёл следующий символ, или пробел.
Хотя я не могу сказать, когда это появилось. Может после того как я Notepa++ привязал к проводнику. Открывал txt файлы в Notepad++ - он себя точно также ведёт.

Странно. Если у вас стоит английской раскладкой US-International попробуйте сменить на что-то другое (просто US или UK). Вдруг поможет.

А так только гуглить и пытаться решить проблему методом тыка =)

Научился пользоваться. Если нужно, чтобы кавычка проявилась нужно затем нажать пробел. А если после кавычки сразу ввести букву, например "о", то она получается Ö, вот такая. Ну я не понимаю, здесь в коментах тоже самое получается. Наверное виндовс обновился. ä é ÿ ü вот такие значки теперь могу вводить, только ни к чему они мне.

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

Немного разобрался. У меня получается три раскладки. Русская, Английская обычная и английская продвинутая. Переключаются последовательно Alt+Shif, или Alt + 2 раза Shift, если нужно через одну раскладку перескочить. Раньше такого не замечал.

Получается нет, только я это не сразу понял.

Это хорошо, раз проблема решилась =) И все-таки я сильно рекомендую установить Geany, убрав лишние панели он будет места занимать не больше блокнота. Но подсветка синтаксиса, автодополнение названий функций, подсказка списка аргументов для функций - без это никуда. Сам сидел на голом блокноте достаточно долго. Страшно вспомнить.

Блин люди, в двойных кавычках заключаются "регудярные выпажения"! Попробуйте заключить в одинарные возврат (\n) или табуляцию (\t) и увидите че будет.

Не знал про кавычки - попал на сайт, когда уточнял лимит памяти, установленный у провайдера для скриптов. Спасибо.

Спасибо большое! Очень хорошо написано, просто и понятно.

Рад, что пригодилось.

PS
Пример в посте
<?php
$date;
echo 'Сегодняшняя дата: '.$date.'';
?>

Учит плохому :) Правильно будет:

<?php
$date;
echo 'Сегодняшняя дата: ', $date, '';
?>

Т. е. заместо точек использовать запятые.

echo является своего рода функцией и может принимать на вход несколько аргументов (echo $arg1, $arg2, ..., $argn);

Если мы используем точку, то мы объединяем все нужные строчки в одну и передаем ее одним аргументом. При использовании запятой мы, наоборот, каждую подстрочку передаем отдельным аргументом. Что работает в разы быстрее, т. к. конкатенация строк весьма прожорливая операция (понятное дело, что потери в скорости несущественные, но так делать все-таки правильней).

Или вообще использовать heredoc синтаксис для мешанины php и html:
<?php
$date;
echo <<

{$date}
HTML;
?>

По скорости не сравнится с выводом набора аргументов, но зато выглядит понятней (особенно когда надо вывести не одну строчку, а целый блок текста с перемешанным php и html).

Привет. Вставлю свои пять копеек (мош кому будет интересно) насчет скорости выполнения вывода сроковых переменных, сцепленных разными способами.
$text1 = "Hello";
$text2 = " world";
$text3 = "!!!";

$start_t1 = microtime(true);
echo "{$text1}{$text2}{$text3}\t";
$time_1 = microtime(true)-$start_t1;
echo "Сцепление строк в парных кавычках. Время вывода: {$time_1}\n";

$start_t2 = microtime(true);
echo $text1.$text2.$text3."\t";
$time_2 = microtime(true)-$start_t2;
echo "Сцепление строк, используя точки. Время вывода: {$time_2}\n";

$start_t3 = microtime(true);
echo $text1, $text2, $text3, "\t";
$time_3 = microtime(true)-$start_t3;
echo "Сцепление строк, используя запятые. Время вывода: {$time_3}\n";

И результат:
php -f ./test_func.php
Hello world!!! Сцепление строк в парных кавычках. Время вывода: 0.00060582160949707
Hello world!!! Сцепление строк, используя точки. Время вывода: 0.00041508674621582
Hello world!!! Сцепление строк, используя запятые. Время вывода: 0.00085210800170898

Спасибо.

Хотя результаты глаз режут немного. Например, что конкатенация (второй случай) работает в два раза быстрее, чем просто список аргументов (третий). Видимо, просто сильная погрешность выходит на одной итерации. Сейчас прогнал каждый из примеров в цикле по 100к раз - результаты для всех трех вариантов плюс-минус одинаковые получились, что уже вполне ожидаемо.

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