1
0
mirror of https://github.com/php/doc-ru.git synced 2026-03-23 23:32:16 +01:00
Files
archived-doc-ru/faq/using.xml
2026-02-20 09:34:31 +03:00

382 lines
18 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 1709768e97fce7848c62aa2bf988419527bd1e8e Maintainer: shein Status: ready -->
<!-- Reviewed: no -->
<chapter xml:id="faq.using" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Использование PHP</title>
<titleabbrev>Использование PHP</titleabbrev>
<para>
Этот раздел собрал множество общих ошибок, которые встречаются при написании PHP-скриптов.
</para>
<qandaset>
<qandaentry xml:id="faq.using.parameterorder">
<question>
<para>
Я не могу запомнить порядок аргументов PHP-функций, они что, случайны?
</para>
</question>
<answer>
<para>
Язык PHP — клей, который скрепляет между собой сотни внешних библиотек,
поэтому иногда это кажется довольно запутанным. Однако, общее правило такое:
</para>
<para>
Параметры <link linkend="book.array">функций работы с массивами</link> упорядочены
в виде «<emphasis>иголка (needle), стог (haystack)</emphasis>», тогда как
порядок <link linkend="book.strings">в строковых функциях</link> обратный,
то есть аналогичен «<emphasis>стог, иголка</emphasis>».
</para>
<para>
C PHP 8.0 <link linkend="functions.named-arguments">именованные аргументы</link>
разрешили передачу аргументов по названию параметра и снизили значимость порядка параметров.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.anyform">
<question>
<para>
Я хочу написать общий PHP-скрипт, который умеет обрабатывать данные,
которые приходят из формы. Как узнать, какие переменные POST-метода
доступны?
</para>
</question>
<answer>
<para>
PHP предлагает множество <link linkend="language.variables.predefined">предопределённых переменных</link>
наподобие суперглобальной переменной <varname>$_POST</varname>. Переменная <varname>$_POST</varname> поддерживает обход элементов в цикле,
поскольку это ассоциативный массив значений, которые поступили в POST-запросе.
Например, просто пройдёмся по элементам массива конструкцией &foreach;,
проверим значения на пустоту (<function>empty</function>) и выведем.
<programlisting role="php">
<![CDATA[
<?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;
}
]]>
</programlisting>
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.addslashes">
<question>
<para>
Требуется заменить одинарные кавычки (') на кавычки с обратным слешем (\').
Как это сделать через регулярное выражение? И тот же вопрос касается замены " на \" и \ на \\.
</para>
</question>
<answer>
<para>
Задействуйте внутренний механизм экранирования базы данных,
если речь идёт о базе данных. Например, вызывайте функцию
<function>mysql_real_escape_string</function> в БД MySQL
и функцию <function>pg_escape_string</function> в базе данных PostgreSQL.
В предыдущих версиях PHP чаще вызывали функции <function>addslashes</function>
и <function>stripslashes</function>.
</para>
<para>
Экранирование значений вручную чревато ошибками и зависит от контекста.
Лучше предпочесть API баз данных, которые поддерживают подготовленные запросы
и привязку параметров, вместо построения запросов путём конкатенации экранированных строк.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.wrong-order">
<question>
<para>
Когда я пишу следующий код, данные выводятся в неправильном порядке:
<programlisting role="php">
<![CDATA[
<?php
function myfunc($argument)
{
echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
]]>
</programlisting>
Что происходит?
</para>
</question>
<answer>
<para>
Чтобы использовать результат функции в выражении
(например, соединении с другими строками, как в приведённом примере),
необходимо вернуть значение инструкцией
<function>return</function>,
а не выводить его через языковую конструкцию <function>echo</function>.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.newlines">
<question>
<para>
Эй, что произошло со строками?!
<programlisting role="php">
<![CDATA[
<pre>
<?php echo "Это должно быть на первой строке."; ?>
<?php echo "А это должно быть на следующей строке."; ?>
</pre>
]]>
</programlisting>
</para>
</question>
<answer>
<para>
В PHP блок кода завершается либо с «?&gt;», либо с «?&gt;\n»
(где \n означает «новая строка»). В приведённом примере
предложения выведутся на одной строке, поскольку PHP опускает
символ новой строки после завершения блока. Это означает,
что необходимо вставить дополнительный символ новой строки
после каждого блока PHP-кода, чтобы вывод продолжался
с новой строки.
</para>
<para>
Почему PHP делает это? Потому что при форматировании обычной HTML-разметки
это обычно упрощает жизнь, потому что новая строка не нужна,
но чтобы получить такой же эффект, пришлось бы создавать очень длинные строки
или другим образом делать исходный текст страницы нечитаемым.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.headers-sent">
<question>
<para>
Я получаю сообщение
'Warning: Cannot send session cookie - headers already
sent...' или 'Cannot add header information - headers already sent...'.
</para>
</question>
<answer>
<para>
Функциям <function>header</function>, <function>setcookie</function>,
и <link linkend="ref.session">функциям сессии</link> нужно добавить
заголовки к выходному потоку, но заголовки разрешается отправлять только перед
другим содержимым. Перед вызовом этих функций нельзя ничего
выводить, в том числе HTML. Функция <function>headers_sent</function>
проверит, послал ли уже скрипт заголовки; также смотрите
<link linkend="ref.outcontrol">функции управления выводом</link>.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.header">
<question>
<para>
Требуется прямой доступ к информации в заголовке запроса.
Как это можно сделать?
</para>
</question>
<answer>
<para>
Это делает функция <function>getallheaders</function>, если
PHP запускается как модуль Apache. Так, следующий кусок кода
покажет все заголовки запроса:
<programlisting role="php">
<![CDATA[
<?php
$headers = getallheaders();
foreach ($headers as $name => $content) {
echo "headers[$name] = $content<br />\n";
}
]]>
</programlisting>
</para>
<para>
Также смотрите
<function>apache_lookup_uri</function>,
<function>apache_response_headers</function>
и <function>fsockopen</function>
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.authentication">
<question>
<para>
При попытке аутентифицироваться на IIS-сервере получаю
'No Input file specified'.
</para>
</question>
<answer>
<para>
Это недостаток модели безопасности IIS. Проблема общая для всех
CGI-программ, которые выполняются под IIS. Чтобы обойти проблему,
создайте простой HTML-файл (который не обрабатывается PHP) как входную страницу
в аутентифицируемой директории. Затем используйте мета-тег для
перенаправления на PHP-страницу или поместите ссылку, которая указывает на PHP-страницу.
После этого PHP распознает аутентификацию правильно.
Это не должно повлиять на другие
веб-серверы NT. Для дополнительной информации смотрите:
<link xlink:href="&url.iis;">&url.iis;</link> и раздел руководства
<link linkend="features.http-auth">HTTP-аутентификация</link>.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.iis.sharing">
<question>
<para>
Windows: с IIS-сервера невозможно получить доступ к файлам,
к которым предоставили общий доступ на другом компьютере.
</para>
</question>
<answer>
<para>
Необходимо сделать изменения. Идите в <literal>Internet Information
Services</literal>. Найдите PHP-файл и перейдите в его свойства.
Идите в закладку <literal>File Security</literal>, <literal>Edit -&gt;
Anonymous access and authentication control</literal>.
</para>
<para>
Можно исправить проблему, либо сняв отметку с <literal>Anonymous
Access</literal> и оставив отмеченным <literal>Integrated Window
Authentication</literal>, либо отметив <literal>Anonymous
Access</literal> и отредактировав права пользователя, поскольку у него
может не быть прав.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.mixml">
<question>
<para>
Как совмещать XML-файл с PHP? Он жалуется на мои &lt;?xml тэги!
</para>
</question>
<answer>
<para>
Чтобы встроить &lt;?xml напрямую в PHP-код, необходимо отключить
короткие теги, установив для PHP-директивы
<link linkend="ini.short-open-tag">short_open_tags</link> значение
<literal>0</literal>. Можно установить эту директиву функцией
<function>ini_set</function>. Независимо от того, включена
опция <link linkend="ini.short-open-tag">short_open_tags</link> или нет,
можно делать что-то вроде:
<literal>&lt;?php echo '&lt;?xml'; ?&gt;</literal>.
По умолчанию эта директива включена (<literal>On</literal>).
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.variables">
<question>
<para>
Где найти полный список переменных, которые доступны в PHP?
</para>
</question>
<answer>
<para>
Читайте страницу руководства по
<link linkend="language.variables.predefined">предопределённым
переменным</link>, поскольку она содержит частичный список предопределённых
переменных, доступных скрипту. Полный список доступных переменных
(и множество другой информации) можно увидеть, вызвав функцию
<function>phpinfo</function>. Не забудьте прочитать раздел руководства
<link linkend="language.variables.external">по переменным, которые лежат вне PHP
</link>, поскольку оно описывает общие сценарии для внешних переменных наподобие
HTML-форм, Cookie и URL-адресов.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.freepdf">
<question>
<para>
Как генерировать PDF-файлы без платных или коммерческих библиотек наподобие PDFLib?
Хотелось бы что-нибудь бесплатное, что не требует внешних PDF-библиотек.
</para>
</question>
<answer>
<para>
На PHP написали ряд альтернативных решений наподобие
<link xlink:href="&url.pdf.fpdf;">FPDF</link>
и <link xlink:href="&url.pdf.tcpdf;">TCPDF</link>.
</para>
</answer>
</qandaentry>
<qandaentry xml:id="faq.using.shorthandbytes">
<question>
<para>
Отдельные PHP-директивы принимают сокращённые байтовые значения,
а не только целочисленные (<type>int</type>) байтовые значения.
Какие варианты сокращений доступны?
</para>
</question>
<answer>
<para>
Доступные варианты: K — килобайты, M — мегабайты и G — гигабайты; значения регистронезависимы.
Всё остальное рассматривается как байты.
Значение <literal>1M</literal> равно одному мегабайту или <literal>1 048 576</literal> байтам.
Значение <literal>1K</literal> равно одному килобайту или <literal>1024</literal> байтам.
Эти сокращения можно указывать в файле &php.ini; и в функции <function>ini_set</function>.
Обратите внимание, что числовое значение приводится к целому числу (<type>int</type>);
например, значение <literal>0.5M</literal> интерпретируется как <literal>0</literal>.
</para>
<note>
<title>килобайт и кибибайт</title>
<para>
В PHP-нотации один килобайт равен 1024 байтам, тогда как стандарт
<acronym>IEC</acronym> считает это кибибайтом.
В итоге: и килобайт (k), и кибибайт (K) рассматриваются как равные 1024 байтам.
</para>
</note>
</answer>
</qandaentry>
</qandaset>
</chapter><!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->