Xpoint
   [напомнить пароль]

FAQ форума Программирование::PHP

Давайте его к человеческому (современному) виду приведём.

Оглавление

Как правильно читать ман. Все перечитал, а нужного не нашел…

Учимся читать ман

Полезные ссылки

  1. http://www.google.com. Это, без шуток, самая важная ссылка по PHP. При некотором умении в ней можно нейти ответ на любой вопрос. Но даже и не обладая особыми навыками в поиске, можно получать потрясающие результаты. Например, просто введите в строку поиска ту ошибку, которую выдал РНР.
  2. Языки программирования — PHP на webclub.ru — www.webclub.ru/content/programming_php. Ссылка оставлена в мемориальных целях…
  3. Официальная документация по PHP. Самая главная, полная, подробная и актуальная, с комментариями пользователей.
  4. Собрание ссылок на различные варианты документации, в том числе и русские переводы — http://phpfaq.ru/docs
  5. phpfaq.ru — Ответы на САМЫЕ ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ. Обязательно к прочтению. Вы обязательно столкнетесь с каждым из освещенных там вопросов.
  6. Клуб российских PHP разработчиков — http://www.phpclub.net/. Там же — самая мощная система форумов по PHP в России.
  7. Самый известный, наверное, российский ресурс — PHP по-русски.
  8. Сайт Дмитрия Котерова, автора книги «Самоучитель по РНР», постоянного посетителя данного форума. Содержит значительное количество интересных материалов и оригинальных разработок, таких как «Денвер» и «Орфо».
  9. WebScript.Ru — каталог Internet, в котором собраны преимущественно свободно распространяемые скрипты, документация по языкам программирования Perl и PHP. Неплохой форум.
  1. ЧПУ и PHP — Дмитрий Смирнов пишет про ЧПУ (Человекопонятный УРЛ :-), в том числе — и про обработку 404-й ошибки (когда запрашиваемый документ не был найден).
  2. Числа прописью.
  3. PHP в деталях. Собрание авторских статей на самые разные темы, посвященные РНР и часто задаваемым вопросам по нему.
  4. Помоги себе сам: как правильно задавать вопросы. Обширный текст, который реально может помочь с тем, как найти ответ на свой вопрос, и как правильно задать его в форуме.

Некоторые западные ресурсы:

  1. http://www.phpwizard.net/ — ресурс, ориентированный на PHP. Проекты (такие как phpMyAdmin, phpChat), ссылки, руководства и т.п.
  2. http://www.phpbuilder.com/ — статьи. Много и умные.
  3. http://www.zend.com/ — «Zend — лидер в технологии PHP. Наша миссия — в том, чтобы обеспечить коммерческую жизнеспособность и поддержку PHP решений для Web.»
  4. http://www.soysal.com/PHPEd/ — небольшой редактор, сделанный по подобию HomeSite, но для PHP.
  5. http://www.hotscripts.com/PHP/ — одно из самых больших собраний готовых скриптов.
  6. http://sourceforge.net/ — сервис для разработчиков, работающих по принципу Открытого Исходного Кода: форумы, исходники и т.п.
  7. http://www.devshed.com/Server_Side/PHP/
  8. WeberDev.com (англ.) — «…был задуман в качестве демонстрации примеров кода, так, чтобы это было более легко для программистов новичка в области php…»
  9. Графическая библиотека GD (англ.) — A graphics library for fast image creation.

Передача из формы параметров с множественным значением (коллекция SELECT multiple и т.п.)

При передаче данных из одного файла PHP далее для обработки передается массив вида имя_элемента => значение. Но есть некоторые элементы (например, select с опцией множественного выбора multiple), где в качестве значения фигурирует не одно, а группа (коллекция). Что делать в этом случае?

Такие элементы передаются в виде массива. Для этого в HTML коде подобного элемента в name следует указать []. Например:

<select name="collect[]" multiple="yes">
   <option value="one">one</option>
   <option value="two">two</option>
   <option value="three">three</option>
   <option value="next">next</option>
</select>

В этом случае в принимающий PHP-скрипт попадет массив под именем $_REQUEST['collect'], содержащий все выбранные значения.

Подобный прием можно использовать для объединения в коллекцию и других параметров формы:

<!-- php скрипт, демонстрирующий получение коллекций -->
<html>
<head><title>Get Collection</title></head>
<body>
<form method="post" action="">

   <!-- элементы типа checkbox объединяются в массив collect1 -->
   <input type="checkbox" name="collect1[]" value="chk1"> one<br>
   <input type="checkbox" name="collect1[]" value="chk2"> two<br>
   <input type="checkbox" name="collect1[]" value="chk3"> три

   <p>
   <!-- массив collect2 служит для передачи значения SELECT с множественным выбором -->
   <select name="collect2[]" multiple="yes">
      <option value="one">one</option>
      <option value="two">two</option>
      <option value="three">three</option>
      <option value="next">next</option>
   </select>

   <p>
   <input type="submit" name="Submit" value="post">
</form>

<?php
if(!empty($_REQUEST['collect1'])) {
   echo "<p><b>Checkboxes:</b><br />";
   foreach($_REQUEST['collect1'] as $i=>$value) {
      echo "$value<br />";
   }
} 
if(!empty($_REQUEST['collect1'])) {
   echo "<p><b>Selected:</b><br />";
   foreach($_REQUEST['collect2'] as $i=>$value) {
      echo "$value<br />";
   }
}
?>
</body>
</html>

Как сделать upload картинки через форму?

Простой HTML-код для организации закачки файла с компьютера пользователя выглядит так:

<html>
<head><title>Upload</title></head>
<body>
<!-- указание enctype="multipart/form-data" является обязательным!!! -->
<form method="post" action="upload.php" enctype="multipart/form-data">
   <b>Файл:</b><br />
   <input type="file" name="userfile"><br />
   <input type="submit" value="Закачать">
</form>
</body>
</html>

Принимающий скрипт выглядит примерно так:

<?php

// путь к директории, в которую будут сохраняться файлы
$path = "/repository/";

if(!empty($_FILES['userfile'])) {
   // путь, в который запишется наш файл
   $uploadfile = $path.basename($_FILES['userfile']['name']);
   if(move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
      echo 'Файл успешно загружен!';
   } else {
      echo 'При загрузке файла возникла ошибка';
   }
}
?>

Замечание: Достаточно частой ошибкой является перекодирование http-сервером принимаемых данных. Если у Вас русский Apache, то эта проблема исправляется выставлением директивы:

CharsetRecodeMultipartForms off

Эта директива может быть выставлена как в файле httpd.conf, так и в .htaccess.

Как я могу вызвать PHP-скрипт внутри другого скрипта и передать туда некоторые переменные? Что-то аналогичное <!--#include virtual="second.php3?my_var=test" --> для SSI

Используйте include "second.php"; или require "second.php";

Вложенный таким образом скрипт будет включен в место вызова этих конструкций, как если бы вы вставили его туда с помощью Copy-Paste.

Как можно прочитать строку из файла?

Помимо использования функция fgetc, fgets и fgetss, Вы можете использовать $file = file($filename). Функция file читает файл $filename в массив $file.

Пример:

<?php
$file = file($filename);
foreach($file as $line) {
    echo $file[$i]."<br />";
}
?>

Прочитать в одну переменную весь файл целиком можно с помощью функции file_get_contents.

Как передать значение переменной из PHP скрипта в функцию JavaScript или в HTML-код?

Просто вывести их как <?=somephpvar?>. Пример:

<?php
$somephpvar = "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
?>

<script type="text/javascript">
    var somejsvar = "<?=$somephpvar?>";
    alert(somejsvar);
</script>

<form action="<?=$somephpvar?>" method="post">
   <input type="submit" name="submit" value="ok">
</form>

Как я могу перенаправить посетителя на другой URL из PHP-скрипта?

Воспользоваться функцией header:

<?php
header("Location: $URL");
exit;
?>

Учтите, что $URL должен содержать абсолютный путь — с http:// и доменом.

Как сделать так, чтоб не выдавалась строка «Content-Type…», когда я запускаю PHP из командной строки?

Некоторые параметры вызова php:

php [-qhsvi]
  -q          Quiet-mode - подавление заголовков HTTP
  -s          Подсветка синтаксиса
  -v          Номер версии PHP
  -i          PHP information
  -h          Справка об остальных параметрах

Я использую шифрование паролей с помощью UNIX. Как мне проверить соответствие введенного пароля зашифрованному?

Такое шифрование, то есть хеширование, является односторонним. Это означает, что вы не можете декодировать зашифрованный пароль — вы можете только сравнить два зашифрованных пароля. Например:

<?php
if(md5($InputPassword) == $StoredPassword) {
    echo "Pasword OK...";
} else {
    echo "Password FAIL...";
}
?>

Как узнать URL выполняемого скрипта, страницу, с которой пришел посетитель и т.п.?

В PHP (и не только) существуют предопределенные переменные окружения веб-сервера. Ниже — список для сервера Apache. Как сказано в руководстве: «если Вы используете другой веб-сервер, мы не гарантируем наличия всех, нижеприведенных переменных».

Вот некоторые из таких переменных:

  • $_SERVER['HTTP_REFERER'] — Адрес страницы (если имеется), c которой пользователь был направлен на текущую страницу. Устанавливается агентом пользователя (браузером, менеджером закачек и т.п.); не все агенты устанавливают это значение! Если ваша программа каким-то образом зависит от реферера, не забывайте, что его очень просто подделать.
  • $_SERVER['SERVER_NAME'] — имя сервера, на котором выполняется скрипт, например: www.webclub.ru.
  • $_SERVER['REQUEST_URI'] — URI вызавемого скрипта, например /vars.php.
  • $_SERVER['GATEWAY_INTERFACE'] — Версия спецификации CGI, используемая сервером, например CGI/1.1.
  • $_SERVER['SERVER_SOFTWARE'] — Строка идентификации сервера, указываемая в заголовках при ответе на запросы.
  • $_SERVER['SERVER_PROTOCOL'] — Название и версия протокола обращения к странице, например HTTP/1.0;
  • $_SERVER['REQUEST_METHOD'] — Метод обращения к странице: GET, HEAD, POST, PUT.
  • $_SERVER['QUERY_STRING'] — Строка запрашиваемых в URL параметров при обращении к странице (если есть).
  • $_SERVER['DOCUMENT_ROOT'] — Корневая директория сервера.
  • $_SERVER['REMOTE_ADDR'] — IP адрес, с которого обратились к странице (не всегда достоверный).
  • $_SERVER['REMOTE_PORT'] — Порт, используемый в машине пользователя, чтобы связаться с сервером сети.
  • $_SERVER['SCRIPT_FILENAME'] — Абсолютный путь к скрипту.
  • $_SERVER['PATH_TRANSLATED'] — Путь для файловой системы к вызванному скрипту.
  • $_SERVER['SCRIPT_NAME'] — Имя скрипта.

Полный список находится в разделе Predefined variables руководства по PHP. Также список всех переменных окружения и настроек PHP можно вывести функцией phpinfo. Рекомендуется запускать ее для проверки на каждом новом для Вас хостинге. Встречаются некоторые коварные хостинги, на которых переменные окружения Апача могут определяться не совсем так, как вы ожидаете.

Cookie не устанавливается или выдается сообщение об ошибке при обращении к SetCookie.

Дело в том, что Cookie явлается частью HTTP-заголовка документа. Вызов функции setcookie должен происходить до окончания вывода HTTP-заголовка (подробнее см. Hypertext Transfer Protocol — HTTP/1.1).

На практике это означает, что если перед вызовом setcookie() есть какой-либо вывод — echo, HTML-текст вне PHP-кода, или если PHP-скрипт, устанавливаюший Cookie, вызывается включением SSI через <!--#include ... --> — то setcookie() выдает ошибку или (в последнем случае) cookie просто не установится.

Если Вы не можете вызвать setcookie() в начале скрипта, то можно включить буферизацию вывода. Для этого вставьте вызов функции ob_start раньше любого вывода в браузер:

<?php
ob_start();
// а дальше всё что угодно

Эта функция заставит PHP ждать, пока отработает весь скрипт, и только потом отдавать данные веб-серверу. Таким образом можно отправлять заголовки в любое время независимо от выводимой информации.

Как отследить повторный вызов скрипта при обновлении страницы?

Скрипт отрисовывает форму и посылает данные post-ом самому себе. Если все правильно — добавляем запись и делаем перенаправление с помощью заголовка Location (перенаправление помешает пользователю отправить те же самые данные дважды путем рефреша страницы). Если не все правильно — опять рисуем форму и выдаем сообщение об ошибке.

Как отключить кеширование страницы PHP-скрипта?

Для этого нужно выставить следующие заголовки:

<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Cache-Control: post-check=0,pre-check=0", false);
header("Cache-Control: max-age=0", false);
header("Pragma: no-cache");
?>

Работа с сокетами. Пример: как скачать файл(страничку) через прокси.

Прокси-сервер: IP: 192.165.0.10 PORT: 3128

<?php
// так выглядит запрос 
$head = "GET http://www.rambler.ru HTTP/1.1\r\n\r\n"; 

// соединяемся с прокси сервером 
$fp = fsockopen("192.165.0.10", 3128); 

if($fp) {// если все cool, то... 
   // передаем запрос 
   fputs($fp, $head); 
   // читаем 65000 байт 
   $returndata = fread($fp, 65000); 
   // закрываем соединение 
   fclose($fp); 
} 
// выводим результат 
print $returndata; 
?>

(с) Сергей Захаров (aka ERge)[досье]

Ручной Download, или как скриптом открыть пользователю окошко сохранения файла.

Чтобы в браузере открылся диалог «Сохранить файл» с названием файла file.dat, скрипт должен послать такие заголовки:

<?php
header("Content-Disposition: attachment; filename=file.dat");
header("Content-Type: application/x-force-download; name=\"file.dat\"");
?>

Не мешало бы также ссылаться на скрипт как http://.../download.php?file.dat, иначе браузеры, основанные на Mozilla, могут попытаться записать файл как file.dat.php.

Примечание: Не используйте заголовок Cache-Control: no-cache в таких скриптах — большинство версий Internet Explorer не смогут скачать файл. (c) Владимир Палант[досье]

Настройка PHP с помощью файла .htaccess

Многие опции, обычно указываемые в файле php.ini, могут быть изменены с помощью файла .htaccess. Существует два формата:

php_value <option_name> <value>
php_flag <option_name> 1|0

Например:

php_value auto_prepend_file /path/from/root/directory/authorise.inc.php

Или так:

php_flag display_errors 1

Разумеется, следует помнить о том, что действие .htaccess распространяется на текущую и вложенные директории, и в конфигурации Апача должна быть задана опция AllowOverride Options (или AllowOverride All). Подробнее про работу с .htaccess читайте в руководстве по Apache.

Как заставить Sablotron говорить по-русски?

Что по этому поводу пишет производитель:
http://www.gingerall.com/charlie/ga/xml/l_sab_faq.xml#q7

Более полный ответ здесь:
http://faq.phpclub.net/index.p......select=41&document_id_select=2

Обновление картинки, сформированной php-скриптом

Варианты решения:

  1. Выдавать заголовки, отключающие кеширование.
  2. Добавлять в конец ссылки, запрашивающей картинку, какую-то случайную величину:
function ShowPic() {
   document.images["pic"].src = "http://127.0.0.1/php/echo_test.php?"+Math.random();
}

Или так:

<?php
srand ((double) microtime() * 1000000);
echo "<img src='http://127.0.0.1/php/echo_test.php?смысловые_параметры&rnd=".rand()."'>";
?>

Удобно в качестве случайной величины использовать дату модификации картинки, если таковую возможно получить.

Как из РНР узнать разрешение экрана у пользователя?

Никак. РНР исполняется на сервере и ничего о компьютере клиента не знает.

В php.ini отключено использование cookies для передачи SID в сессиях, но PHP всё равно пытается передавать SID в куках и не пытается даже подставлять SID в ссылки.

Убедитесь, что нужные параметры выставлены правильно:

session.use_trans_sid  1
session.use_cookies    0

Где можно найти информацию для начинающих в РНР?

http://www.myphp.dem.ru/
http://php.itsoft.ru/
http://virtual.bresttelecom.by/php/
http://www.providerz.ru/articles/php/

Где взять русскую документацию по РНР4? А по MySQL?

Человек по имени Александр Пирамидин перевел документацию от версии 4.2.1 (зеркало на PHPClub-е). Этот перевод вполне подходит для изучения PHP, но надо помнить, что наиболее точной является документация на оригинальном сайте.

Также частично переведенный мануал можно найти на php.ru.

Русская документация по MySQL: http://www.mysql.com/doc/ru/

Не передаются переменные!!!

Данные в скрипт передаются. Просто, начиная с версии 4.1, РНР перестал автоматически назначать их переменным. За это отвечает параметр register_globals в php.ini. Если он выключен, то получить значение переменной можно, обратившись к массиву, соответствующему способу передачи данных в скрипт.
Например:
Передаем методом GET: script.php?var=value — echo $_GET['var'] напечатает «value».
Подробнее об этом можно прочитать здесь: http://www.xpoint.ru/archive/topic8/43/8759.html

Как писать русскими буквам в GD без TrueType?

Вот есть такая страничка http://www.sbnet.ru/soft/gdfonts/pages/index.htm
Там написано, как в gd рисовать по-русски, не дергая truetype при этом.
(c) Гоша

Почему разработчики PHP не рекомендуют использовать его с Apache 2.x?

  1. Apache2 по всем тестам работает процентов на 15-20 медленнее Apache 1.3*. Этот факт давно известен, в том числе и разработчикам Apache. Выигрыш от его использования может быть только на очень больших сайтах и заключается только в меньшем расходе памяти при большой нагрузке (100 процессов httpd жрут памяти больше, чем 100 нитей Apache2). В Apache2, несмотря на то, что разработчики называют его стабильным, довольно часто находят довольно серьезные баги. Это объяснимо, учитывая то, что код Apache2 еще достаточно новый, в отличие от вылизанного временем кода Apache1.3
  1. В PHP полно расширений, при программировании которых не была применена практика безопасного программирования для нитей (thread-safe). Поэтому, даже если ядро языка перестанет быть экспериментальным для Apache2, никто не гарантирует, что любое из расширений не сможет вызвать крах системы.
  1. Наконец, последняя версия Apache2 нисколько не "свежее" последней версии ветки 1.3.

Максим Деркачев[досье]

Как средствами GD поместить прозрачный логотип на свою фотографию

Если Вы хотите поместить прозрачное PNG-изображение на другое изображение, необходимо использовать ImageAlphaBlending. Все использующиеся PNG-изображения должны быть сохранены в формате PNG-24 (опция Save for Web в Фотошопе). Например, Вы хотите поместить прозрачный логотип на свою фотографию. Тогда нужно сделать так:

<?php
$photoImage = ImageCreateFromJPEG("photo.jpg");
ImageAlphaBlending($photoImage, true);

$logoImage = ImageCreateFromPNG("logo.png");
$logoW = ImageSX($logoImage);
$logoH = ImageSY($logoImage);
ImageCopy($photoImage, $logoImage, 0, 0, 0, 0, $logoW, $logoH);

ImageJPEG($photoImage); // вывод в браузер 
?>

Как прочитать скриптом данные, посланные методом POST напрямую?

  1. Размер блока пришедших данных содержится в переменной окружения CONTENT_LENGTH и читается из $_ENV["CONTENT_LENGTH"] или getenv("CONTENT_LENGTH").
  1. Если PHP установлен как CGI и ваша программа работает из командной строки (в консольном режиме), данные можно читать из стандартного потока ввода stdin, как из обычного файла. Для этого достаточно открыть этот поток как файл:
$stdin = fopen("php://stdin", "r");
  1. Если PHP установлен как модуль, данные можно получить из глобальной переменной $HTTP_RAW_POST_DATA (она же $GLOBALS['HTTP_RAW_POST_DATA']). Для этого необходимо в файле php.ini раскомментировать/добавить следующую строчку:
always_populate_raw_post_data = On

Или добавить в файл .htaccess:

php_flag always_populate_raw_post_data On

Однако это все равно не сработает, если запрос был отправлен с enctype="multipart/form-data" (устанавливается при загрузке файлов).

Как сделать красивую превьюшку средствами GD

Для этого рекомендутся воспользоваться функциями imagecreatetruecolor (для создания новой «правильноцветной» картинки и функцией imagecopyresampled (для создания уменьшенной копии исходной картинки).

Как форсировать кеширование динамически выдаваемых картинок?

<?php
// кеш-френдли вывод картинки
$fname = @$_GET['fname']; // обязательно проверить имя!
if(!is_readable($fname)) exit();
$headers = getallheaders();
$rtime = strtotime(@$headers['If-Modified-Since']);
$mtime = filemtime($fname);
if($rtime >= $mtime) {
  header("HTTP/1.0 304 Not Modified");
  exit();
}
header('Content-Type: application/x-shockwave-flash'); // не забудьте указать правильный тип
header('Content-Length: '.filesize($fname));
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT');
header('Cache-control: public');
readfile($fname);
?>

Функция mail слишком долго отправляет письма. Как можно ускорить процесс отправки?

Отправлять письма не в рамках выполнения основного скрипта, а посредством создания еще одного процесса, выполняемого в фоновом режиме.

XSLT-преобразования в PHP. Sablotron error on line 1: XML parser error 4: not well-formed (invalid token)

Несмотря на то, что написано в документации, реально в качестве аргументов xslt_process надо передавать не имена файлов, а их содержимое:

<?php
$arguments = array(
    '/_xml' => $xml,
    '/_xsl' => $xsl
);
$res = xslt_process($xs,'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
?>

Исследования же Михаила Кюршина выявили, что xslt_process принимает адреса файлов. Нужен именно адрес (URL), а не путь на диске. К примеру, file:///C:/xxx/ooo.xml — это адрес, а C:/xxx/ooo.xml — это путь на диске.

Как проверить, полностью ли докачался файл у пользователя (то есть, не отменил ли он загрузку на середине или вдруг у него инет вырубило)?

Средствами php это невозможно. Если вам это действительно нужно, почитайте, например, как Иван Сагалаев решал похожую задачу на языке python.

Powered by POEM™ Engine Copyright © 2002-2005