mirror of
https://github.com/php/doc-ru.git
synced 2026-03-23 23:32:16 +01:00
382 lines
18 KiB
XML
382 lines
18 KiB
XML
<?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 блок кода завершается либо с «?>», либо с «?>\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 ->
|
||
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? Он жалуется на мои <?xml тэги!
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>
|
||
Чтобы встроить <?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><?php echo '<?xml'; ?></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
|
||
-->
|