<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/faq.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'faq.using.php',
    1 => 'Использование PHP',
    2 => 'Использование PHP',
  ),
  'up' => 
  array (
    0 => 'faq.php',
    1 => 'ЧАВО',
  ),
  'prev' => 
  array (
    0 => 'faq.build.php',
    1 => 'Проблемы сборки',
  ),
  'next' => 
  array (
    0 => 'faq.passwords.php',
    1 => 'Хеширование паролей',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'faq/using.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="faq.using" class="chapter">
  <h1 class="title">Использование PHP</h1>

  

  <p class="para">
   Этот раздел собрал множество общих ошибок, которые встречаются при написании PHP-скриптов.
  </p>

  <div class="qandaset"><ol class="qandaset_questions"><li><a href="#faq.using.parameterorder">
     
      Я не могу запомнить порядок аргументов PHP-функций, они что, случайны?
     
    </a></li><li><a href="#faq.using.anyform">
     
      Я хочу написать общий PHP-скрипт, который умеет обрабатывать данные,
      которые приходят из формы. Как узнать, какие переменные POST-метода
      доступны?
     
    </a></li><li><a href="#faq.using.addslashes">
     
      Требуется заменить одинарные кавычки (&#039;) на кавычки с обратным слешем (\&#039;).
      Как это сделать через регулярное выражение? И тот же вопрос касается замены &quot; на \&quot; и \ на \\.
     
    </a></li><li><a href="#faq.using.wrong-order">
     
      Когда я пишу следующий код, данные выводятся в неправильном порядке:
     

&lt;?php

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

$variable = 10;

echo &quot;myfunc($variable) = &quot; . myfunc($variable);

    
     Что происходит?
     
    </a></li><li><a href="#faq.using.newlines">
     
      Эй, что произошло со строками?!
      

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

      
     
    </a></li><li><a href="#faq.using.headers-sent">
     
      Я получаю сообщение
      &#039;Warning: Cannot send session cookie - headers already
      sent...&#039; или &#039;Cannot add header information - headers already sent...&#039;.
     
    </a></li><li><a href="#faq.using.header">
     
      Требуется прямой доступ к информации в заголовке запроса.
      Как это можно сделать?
     
    </a></li><li><a href="#faq.using.authentication">
     
      При попытке аутентифицироваться на IIS-сервере получаю
      &#039;No Input file specified&#039;.
     
    </a></li><li><a href="#faq.using.iis.sharing">
     
      Windows: с IIS-сервера невозможно получить доступ к файлам,
      к которым предоставили общий доступ на другом компьютере.
     
    </a></li><li><a href="#faq.using.mixml">
     
      Как совмещать XML-файл с PHP? Он жалуется на мои &lt;?xml тэги!
     
    </a></li><li><a href="#faq.using.variables">
     
      Где найти полный список переменных, которые доступны в PHP?
     
    </a></li><li><a href="#faq.using.freepdf">
     
      Как генерировать PDF-файлы без платных или коммерческих библиотек наподобие PDFLib?
      Хотелось бы что-нибудь бесплатное, что не требует внешних PDF-библиотек.
     
    </a></li><li><a href="#faq.using.shorthandbytes">
     
      Отдельные PHP-директивы принимают сокращённые байтовые значения,
      а не только целочисленные (int) байтовые значения.
      Какие варианты сокращений доступны?
     
    </a></li></ol></div>

   <dl class="qandaentry" id="faq.using.parameterorder">
    <dt><strong>
     
      Я не могу запомнить порядок аргументов PHP-функций, они что, случайны?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Язык PHP — клей, который скрепляет между собой сотни внешних библиотек,
      поэтому иногда это кажется довольно запутанным. Однако, общее правило такое:
     </p>
     <p class="para">
      Параметры <a href="book.array.php" class="link">функций работы с массивами</a> упорядочены
      в виде «<em>иголка (needle), стог (haystack)</em>», тогда как
      порядок <a href="book.strings.php" class="link">в строковых функциях</a> обратный,
      то есть аналогичен «<em>стог, иголка</em>».
     </p>
     <p class="para">
      C PHP 8.0 <a href="functions.arguments.php#functions.named-arguments" class="link">именованные аргументы</a>
      разрешили передачу аргументов по названию параметра и снизили значимость порядка параметров.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.anyform">
    <dt><strong>
     
      Я хочу написать общий PHP-скрипт, который умеет обрабатывать данные,
      которые приходят из формы. Как узнать, какие переменные POST-метода
      доступны?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      PHP предлагает множество <a href="language.variables.predefined.php" class="link">предопределённых переменных</a>
      наподобие суперглобальной переменной <var class="varname"><a href="reserved.variables.post.php" class="classname">$_POST</a></var>. Переменная <var class="varname"><a href="reserved.variables.post.php" class="classname">$_POST</a></var> поддерживает обход элементов в цикле,
      поскольку это ассоциативный массив значений, которые поступили в POST-запросе.
      Например, просто пройдёмся по элементам массива конструкцией <a href="control-structures.foreach.php" class="link"><code class="literal">foreach</code></a>,
      проверим значения на пустоту (<span class="function"><a href="function.empty.php" class="function">empty()</a></span>) и выведем.
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$empty </span><span style="color: #007700">= </span><span style="color: #0000BB">$post </span><span style="color: #007700">= array();<br /><br />foreach (</span><span style="color: #0000BB">$_POST </span><span style="color: #007700">as </span><span style="color: #0000BB">$varname </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$varvalue</span><span style="color: #007700">) {<br />    if (empty(</span><span style="color: #0000BB">$varvalue</span><span style="color: #007700">)) {<br />        </span><span style="color: #0000BB">$empty</span><span style="color: #007700">[</span><span style="color: #0000BB">$varname</span><span style="color: #007700">] = </span><span style="color: #0000BB">$varvalue</span><span style="color: #007700">;<br />    } else {<br />        </span><span style="color: #0000BB">$post</span><span style="color: #007700">[</span><span style="color: #0000BB">$varname</span><span style="color: #007700">] = </span><span style="color: #0000BB">$varvalue</span><span style="color: #007700">;<br />    }<br />}<br /><br />print </span><span style="color: #DD0000">"&lt;pre&gt;"</span><span style="color: #007700">;<br /><br />if (empty(</span><span style="color: #0000BB">$empty</span><span style="color: #007700">)) {<br />    print </span><span style="color: #DD0000">"В POST не было пустых значений, вот что там было:\n"</span><span style="color: #007700">;<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">);<br />} else {<br />    print </span><span style="color: #DD0000">"Пришло " </span><span style="color: #007700">. </span><span style="color: #0000BB">count</span><span style="color: #007700">(</span><span style="color: #0000BB">$empty</span><span style="color: #007700">) . </span><span style="color: #DD0000">" пустых значений\n"</span><span style="color: #007700">;<br />    print </span><span style="color: #DD0000">"Всего отправлено:\n"</span><span style="color: #007700">; </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">);<br />    print </span><span style="color: #DD0000">"Пустых:\n"</span><span style="color: #007700">; </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$empty</span><span style="color: #007700">);<br />    exit;<br />}</span></span></code></div>
      </div>

     </p>

    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.addslashes">
    <dt><strong>
     
      Требуется заменить одинарные кавычки (&#039;) на кавычки с обратным слешем (\&#039;).
      Как это сделать через регулярное выражение? И тот же вопрос касается замены &quot; на \&quot; и \ на \\.
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Задействуйте внутренний механизм экранирования базы данных,
      если речь идёт о базе данных. Например, вызывайте функцию
      <span class="function"><a href="function.mysql-real-escape-string.php" class="function">mysql_real_escape_string()</a></span> в БД MySQL
      и функцию <span class="function"><a href="function.pg-escape-string.php" class="function">pg_escape_string()</a></span> в базе данных PostgreSQL.
      В предыдущих версиях PHP чаще вызывали функции <span class="function"><a href="function.addslashes.php" class="function">addslashes()</a></span>
      и <span class="function"><a href="function.stripslashes.php" class="function">stripslashes()</a></span>.
     </p>
     <p class="para">
      Экранирование значений вручную чревато ошибками и зависит от контекста.
      Лучше предпочесть API баз данных, которые поддерживают подготовленные запросы
      и привязку параметров, вместо построения запросов путём конкатенации экранированных строк.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.wrong-order">
    <dt><strong>
     
      Когда я пишу следующий код, данные выводятся в неправильном порядке:
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">myfunc</span><span style="color: #007700">(</span><span style="color: #0000BB">$argument</span><span style="color: #007700">)<br />{<br />    echo </span><span style="color: #0000BB">$argument </span><span style="color: #007700">+ </span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$variable </span><span style="color: #007700">= </span><span style="color: #0000BB">10</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #DD0000">"myfunc(</span><span style="color: #0000BB">$variable</span><span style="color: #DD0000">) = " </span><span style="color: #007700">. </span><span style="color: #0000BB">myfunc</span><span style="color: #007700">(</span><span style="color: #0000BB">$variable</span><span style="color: #007700">);</span></span></code></div>
    </div>

     Что происходит?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Чтобы использовать результат функции в выражении
      (например, соединении с другими строками, как в приведённом примере),
      необходимо вернуть значение инструкцией
      <span class="function"><a href="function.return.php" class="function">return</a></span>,
      а не выводить его через языковую конструкцию <span class="function"><a href="function.echo.php" class="function">echo</a></span>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.newlines">
    <dt><strong>
     
      Эй, что произошло со строками?!
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000">&lt;pre&gt;<br /><span style="color: #0000BB">&lt;?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Это должно быть на первой строке."</span><span style="color: #007700">; </span><span style="color: #0000BB">?&gt;<br />&lt;?php </span><span style="color: #007700">echo </span><span style="color: #DD0000">"А это должно быть на следующей строке."</span><span style="color: #007700">; </span><span style="color: #0000BB">?&gt;<br /></span>&lt;/pre&gt;</span></code></div>
      </div>

     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      В PHP блок кода завершается либо с «?&gt;», либо с «?&gt;\n»
      (где \n означает «новая строка»). В приведённом примере
      предложения выведутся на одной строке, поскольку PHP опускает
      символ новой строки после завершения блока. Это означает,
      что необходимо вставить дополнительный символ новой строки
      после каждого блока PHP-кода, чтобы вывод продолжался
      с новой строки.
     </p>
     <p class="para">
      Почему PHP делает это? Потому что при форматировании обычной HTML-разметки
      это обычно упрощает жизнь, потому что новая строка не нужна,
      но чтобы получить такой  же эффект, пришлось бы создавать очень длинные строки
      или другим образом делать исходный текст страницы нечитаемым.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.headers-sent">
    <dt><strong>
     
      Я получаю сообщение
      &#039;Warning: Cannot send session cookie - headers already
      sent...&#039; или &#039;Cannot add header information - headers already sent...&#039;.
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Функциям <span class="function"><a href="function.header.php" class="function">header()</a></span>, <span class="function"><a href="function.setcookie.php" class="function">setcookie()</a></span>,
      и <a href="ref.session.php" class="link">функциям сессии</a> нужно добавить
      заголовки к выходному потоку, но заголовки разрешается отправлять только перед
      другим содержимым. Перед вызовом этих функций нельзя ничего
      выводить, в том числе HTML. Функция <span class="function"><a href="function.headers-sent.php" class="function">headers_sent()</a></span>
      проверит, послал ли уже скрипт заголовки; также смотрите
      <a href="ref.outcontrol.php" class="link">функции управления выводом</a>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.header">
    <dt><strong>
     
      Требуется прямой доступ к информации в заголовке запроса.
      Как это можно сделать?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Это делает функция <span class="function"><a href="function.getallheaders.php" class="function">getallheaders()</a></span>, если
      PHP запускается как модуль Apache. Так, следующий кусок кода
      покажет все заголовки запроса:
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$headers </span><span style="color: #007700">= </span><span style="color: #0000BB">getallheaders</span><span style="color: #007700">();<br /><br />foreach (</span><span style="color: #0000BB">$headers </span><span style="color: #007700">as </span><span style="color: #0000BB">$name </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$content</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"headers[</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">] = </span><span style="color: #0000BB">$content</span><span style="color: #DD0000">&lt;br /&gt;\n"</span><span style="color: #007700">;<br />}</span></span></code></div>
      </div>

     </p>
     <p class="para">
      Также смотрите
      <span class="function"><a href="function.apache-lookup-uri.php" class="function">apache_lookup_uri()</a></span>,
      <span class="function"><a href="function.apache-response-headers.php" class="function">apache_response_headers()</a></span>
      и <span class="function"><a href="function.fsockopen.php" class="function">fsockopen()</a></span>
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.authentication">
    <dt><strong>
     
      При попытке аутентифицироваться на IIS-сервере получаю
      &#039;No Input file specified&#039;.
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Это недостаток модели безопасности IIS. Проблема общая для всех
      CGI-программ, которые выполняются под IIS. Чтобы обойти проблему,
      создайте простой HTML-файл (который не обрабатывается PHP) как входную страницу
      в аутентифицируемой директории. Затем используйте мета-тег для
      перенаправления на PHP-страницу или поместите ссылку, которая указывает на PHP-страницу.
      После этого PHP распознает аутентификацию правильно.
      Это не должно повлиять на другие
      веб-серверы NT. Для дополнительной информации смотрите:
      <a href="http://support.microsoft.com/kb/q160422/" class="link external">&raquo;&nbsp;http://support.microsoft.com/kb/q160422/</a> и раздел руководства
      <a href="features.http-auth.php" class="link">HTTP-аутентификация</a>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.iis.sharing">
    <dt><strong>
     
      Windows: с IIS-сервера невозможно получить доступ к файлам,
      к которым предоставили общий доступ на другом компьютере.
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Необходимо сделать изменения. Идите в <code class="literal">Internet Information
      Services</code>. Найдите PHP-файл и перейдите в его свойства.
      Идите в закладку <code class="literal">File Security</code>, <code class="literal">Edit -&gt;
      Anonymous access and authentication control</code>.
     </p>
     <p class="para">
      Можно исправить проблему, либо сняв отметку с <code class="literal">Anonymous
      Access</code> и оставив отмеченным <code class="literal">Integrated Window
      Authentication</code>, либо отметив <code class="literal">Anonymous
      Access</code> и отредактировав права пользователя, поскольку у него
      может не быть прав.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.mixml">
    <dt><strong>
     
      Как совмещать XML-файл с PHP? Он жалуется на мои &lt;?xml тэги!
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Чтобы встроить &lt;?xml напрямую в PHP-код, необходимо отключить
      короткие теги, установив для PHP-директивы
      <a href="ini.core.php#ini.short-open-tag" class="link">short_open_tags</a> значение
      <code class="literal">0</code>. Можно установить эту директиву функцией
      <span class="function"><a href="function.ini-set.php" class="function">ini_set()</a></span>. Независимо от того, включена
      опция <a href="ini.core.php#ini.short-open-tag" class="link">short_open_tags</a> или нет,
      можно делать что-то вроде:
      <code class="literal">&lt;?php echo &#039;&lt;?xml&#039;; ?&gt;</code>.
      По умолчанию эта директива включена (<code class="literal">On</code>).
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.variables">
    <dt><strong>
     
      Где найти полный список переменных, которые доступны в PHP?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Читайте страницу руководства по
      <a href="language.variables.predefined.php" class="link">предопределённым
      переменным</a>, поскольку она содержит частичный список предопределённых
      переменных, доступных скрипту. Полный список доступных переменных
      (и множество другой информации) можно увидеть, вызвав функцию
      <span class="function"><a href="function.phpinfo.php" class="function">phpinfo()</a></span>. Не забудьте прочитать раздел руководства
      <a href="language.variables.external.php" class="link">по переменным, которые лежат вне PHP
      </a>, поскольку оно описывает общие сценарии для внешних переменных наподобие
      HTML-форм, Cookie и URL-адресов.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.freepdf">
    <dt><strong>
     
      Как генерировать PDF-файлы без платных или коммерческих библиотек наподобие PDFLib?
      Хотелось бы что-нибудь бесплатное, что не требует внешних PDF-библиотек.
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      На PHP написали ряд альтернативных решений наподобие
      <a href="http://www.fpdf.org/" class="link external">&raquo;&nbsp;FPDF</a>
      и <a href="http://www.tcpdf.org/" class="link external">&raquo;&nbsp;TCPDF</a>.
     </p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.using.shorthandbytes">
    <dt><strong>
     
      Отдельные PHP-директивы принимают сокращённые байтовые значения,
      а не только целочисленные (<span class="type"><a href="language.types.integer.php" class="type int">int</a></span>) байтовые значения.
      Какие варианты сокращений доступны?
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      Доступные варианты: K — килобайты, M — мегабайты и G — гигабайты; значения регистронезависимы.
      Всё остальное рассматривается как байты.
      Значение <code class="literal">1M</code> равно одному мегабайту или <code class="literal">1 048 576</code> байтам.
      Значение <code class="literal">1K</code> равно одному килобайту или <code class="literal">1024</code> байтам.
      Эти сокращения можно указывать в файле <var class="filename">php.ini</var> и в функции <span class="function"><a href="function.ini-set.php" class="function">ini_set()</a></span>.
      Обратите внимание, что числовое значение приводится к целому числу (<span class="type"><a href="language.types.integer.php" class="type int">int</a></span>);
      например, значение <code class="literal">0.5M</code> интерпретируется как <code class="literal">0</code>.
     </p>
     <blockquote class="note"><p><strong class="note">Замечание</strong>: 
      <strong>килобайт и кибибайт</strong><br />
      <p class="para">
       В PHP-нотации один килобайт равен 1024 байтам, тогда как стандарт
       <abbr>IEC</abbr> считает это кибибайтом.
       В итоге: и килобайт (k), и кибибайт (K) рассматриваются как равные 1024 байтам.
      </p>
     </p></blockquote>
    </dd>
   </dl>
  
 </div>
<?php manual_footer($setup); ?>