# Использование PHP

Этот раздел собрал множество общих ошибок, которые встречаются при написании PHP-скриптов.

1. Я не могу запомнить порядок аргументов PHP-функций, они что, случайны?
2. Я хочу написать общий PHP-скрипт, который умеет обрабатывать данные, которые приходят из формы. Как узнать, какие переменные POST-метода доступны?
3. Требуется заменить одинарные кавычки (') на кавычки с обратным слешем (\'). Как это сделать через регулярное выражение? И тот же вопрос касается замены " на \" и \ на \\.
4. Когда я пишу следующий код, данные выводятся в неправильном порядке: <?php function myfunc($argument) { echo $argument + 10; } $variable = 10; echo "myfunc($variable) = " . myfunc($variable); Что происходит?
5. Эй, что произошло со строками?! <pre> <?php echo "Это должно быть на первой строке."; ?> <?php echo "А это должно быть на следующей строке."; ?> </pre>
6. Я получаю сообщение 'Warning: Cannot send session cookie - headers already sent...' или 'Cannot add header information - headers already sent...'.
7. Требуется прямой доступ к информации в заголовке запроса. Как это можно сделать?
8. При попытке аутентифицироваться на IIS-сервере получаю 'No Input file specified'.
9. Windows: с IIS-сервера невозможно получить доступ к файлам, к которым предоставили общий доступ на другом компьютере.
10. Как совмещать XML-файл с PHP? Он жалуется на мои <?xml тэги!
11. Где найти полный список переменных, которые доступны в PHP?
12. Как генерировать PDF-файлы без платных или коммерческих библиотек наподобие PDFLib? Хотелось бы что-нибудь бесплатное, что не требует внешних PDF-библиотек.
13. Отдельные PHP-директивы принимают сокращённые байтовые значения, а не только целочисленные (int) байтовые значения. Какие варианты сокращений доступны?

Я не могу запомнить порядок аргументов PHP-функций, они что, случайны?

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

  Параметры функций работы с массивами упорядочены в виде «иголка (needle), стог (haystack)», тогда как порядок в строковых функциях обратный, то есть аналогичен «стог, иголка».

  C PHP 8.0 именованные аргументы разрешили передачу аргументов по названию параметра и снизили значимость порядка параметров.

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

  PHP предлагает множество предопределённых переменных наподобие суперглобальной переменной $_POST. Переменная $_POST поддерживает обход элементов в цикле, поскольку это ассоциативный массив значений, которые поступили в POST-запросе. Например, просто пройдёмся по элементам массива конструкцией `foreach`, проверим значения на пустоту (empty()) и выведем.

      <?php

      $empty = $post = array();

      foreach ($_POST as $varname => $varvalue) {
          if (empty($varvalue)) {
              $empty[$varname] = $varvalue;
          } else {
              $post[$varname] = $varvalue;
          }
      }

      print "<pre>";

      if (empty($empty)) {
          print "В POST не было пустых значений, вот что там было:\n";
          var_dump($post);
      } else {
          print "Пришло " . count($empty) . " пустых значений\n";
          print "Всего отправлено:\n"; var_dump($post);
          print "Пустых:\n"; var_dump($empty);
          exit;
      }

Требуется заменить одинарные кавычки (') на кавычки с обратным слешем (\'). Как это сделать через регулярное выражение? И тот же вопрос касается замены " на \" и \ на \\.

  Задействуйте внутренний механизм экранирования базы данных, если речь идёт о базе данных. Например, вызывайте функцию mysql_real_escape_string() в БД MySQL и функцию pg_escape_string() в базе данных PostgreSQL. В предыдущих версиях PHP чаще вызывали функции addslashes() и stripslashes().

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

Когда я пишу следующий код, данные выводятся в неправильном порядке:

    <?php

    function myfunc($argument)
    {
        echo $argument + 10;
    }

    $variable = 10;

    echo "myfunc($variable) = " . myfunc($variable);

Что происходит?

  Чтобы использовать результат функции в выражении (например, соединении с другими строками, как в приведённом примере), необходимо вернуть значение инструкцией return, а не выводить его через языковую конструкцию echo.

Эй, что произошло со строками?!

    <pre>
    <?php echo "Это должно быть на первой строке."; ?>
    <?php echo "А это должно быть на следующей строке."; ?>
    </pre>

  В PHP блок кода завершается либо с «?>», либо с «?>\n» (где \n означает «новая строка»). В приведённом примере предложения выведутся на одной строке, поскольку PHP опускает символ новой строки после завершения блока. Это означает, что необходимо вставить дополнительный символ новой строки после каждого блока PHP-кода, чтобы вывод продолжался с новой строки.

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

Я получаю сообщение 'Warning: Cannot send session cookie - headers already sent...' или 'Cannot add header information - headers already sent...'.

  Функциям header(), setcookie(), и функциям сессии нужно добавить заголовки к выходному потоку, но заголовки разрешается отправлять только перед другим содержимым. Перед вызовом этих функций нельзя ничего выводить, в том числе HTML. Функция headers_sent() проверит, послал ли уже скрипт заголовки; также смотрите функции управления выводом.

Требуется прямой доступ к информации в заголовке запроса. Как это можно сделать?

  Это делает функция getallheaders(), если PHP запускается как модуль Apache. Так, следующий кусок кода покажет все заголовки запроса:

      <?php

      $headers = getallheaders();

      foreach ($headers as $name => $content) {
          echo "headers[$name] = $content<br />\n";
      }

  Также смотрите apache_lookup_uri(), apache_response_headers() и fsockopen()

При попытке аутентифицироваться на IIS-сервере получаю 'No Input file specified'.

  Это недостаток модели безопасности IIS. Проблема общая для всех CGI-программ, которые выполняются под IIS. Чтобы обойти проблему, создайте простой HTML-файл (который не обрабатывается PHP) как входную страницу в аутентифицируемой директории. Затем используйте мета-тег для перенаправления на PHP-страницу или поместите ссылку, которая указывает на PHP-страницу. После этого PHP распознает аутентификацию правильно. Это не должно повлиять на другие веб-серверы NT. Для дополнительной информации смотрите: » http://support.microsoft.com/kb/q160422/ и раздел руководства HTTP-аутентификация.

Windows: с IIS-сервера невозможно получить доступ к файлам, к которым предоставили общий доступ на другом компьютере.

  Необходимо сделать изменения. Идите в `Internet Information Services`. Найдите PHP-файл и перейдите в его свойства. Идите в закладку `File Security`, `Edit -> Anonymous access and authentication control`.

  Можно исправить проблему, либо сняв отметку с `Anonymous Access` и оставив отмеченным `Integrated Window Authentication`, либо отметив `Anonymous Access` и отредактировав права пользователя, поскольку у него может не быть прав.

Как совмещать XML-файл с PHP? Он жалуется на мои <?xml тэги!

  Чтобы встроить <?xml напрямую в PHP-код, необходимо отключить короткие теги, установив для PHP-директивы short_open_tags значение `0`. Можно установить эту директиву функцией ini_set(). Независимо от того, включена опция short_open_tags или нет, можно делать что-то вроде: `<?php echo '<?xml'; ?>`. По умолчанию эта директива включена (`On`).

Где найти полный список переменных, которые доступны в PHP?

  Читайте страницу руководства по предопределённым переменным, поскольку она содержит частичный список предопределённых переменных, доступных скрипту. Полный список доступных переменных (и множество другой информации) можно увидеть, вызвав функцию phpinfo(). Не забудьте прочитать раздел руководства по переменным, которые лежат вне PHP , поскольку оно описывает общие сценарии для внешних переменных наподобие HTML-форм, Cookie и URL-адресов.

Как генерировать PDF-файлы без платных или коммерческих библиотек наподобие PDFLib? Хотелось бы что-нибудь бесплатное, что не требует внешних PDF-библиотек.

  На PHP написали ряд альтернативных решений наподобие » FPDF и » TCPDF.

Отдельные PHP-директивы принимают сокращённые байтовые значения, а не только целочисленные (int) байтовые значения. Какие варианты сокращений доступны?

  Доступные варианты: K — килобайты, M — мегабайты и G — гигабайты; значения регистронезависимы. Всё остальное рассматривается как байты. Значение `1M` равно одному мегабайту или `1 048 576` байтам. Значение `1K` равно одному килобайту или `1024` байтам. Эти сокращения можно указывать в файле php.ini и в функции ini_set(). Обратите внимание, что числовое значение приводится к целому числу (int); например, значение `0.5M` интерпретируется как `0`.

  > Замечание: килобайт и кибибайт

  > В PHP-нотации один килобайт равен 1024 байтам, тогда как стандарт IEC считает это кибибайтом. В итоге: и килобайт (k), и кибибайт (K) рассматриваются как равные 1024 байтам.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open