×
Техническая документация: Хостинг

PHP: использование программ на языке PHP

Пользователям хостинга предоставляется возможность использовать на своих сайтах программы на языке PHP (в соответствии с тарифным планом). У нас установлена одна из последних версий PHP и мы стараемся по мере возможности ее обновлять. Текущую конфигурацию можно посмотреть при помощи функции phpinfo().

Пример скрипта для просмотра конфигурации PHP:

<?php
phpinfo();
?>

Что такое PHP и как начать с ним работать

PHP: Hypertext Preprocessor — очень простой даже для начинающего веб-программиста язык, который, тем не менее, обладает очень серьезными возможностями. PHP — язык достаточно высокого уровня, что позволяет просто реализовывать на нем именно веб-проекты, не заботясь при этом о ненужных низкоуровневых процессах. Если Вы хотите добавить динамику и интерактив на свой сайт, но при этом не хотите изучать более сложные языки вроде Perl, можно использовать PHP. Этот язык также содержит большое количество встроенных возможностей для работы с популярной СУБД MySQL, что делает выбор PHP для веб-программирования еще более привлекательным.

Начать использовать PHP очень просто: нужно создать в веб-пространстве файл с расширением *.php и поместить в него нужные PHP-инструкции. Например, создадим файл test.php в каталоге www вашего домена и поместим в него следующий текст:

<?php
echo "Hello, world! This is my first program with PHP!"
?>

Теперь откройте страницу http://www.ваш_домен.ru/test.php и Вы увидите результат выполнения скрипта. PHP — это просто. Простоты этому языку добавляет наличие отличной документации на русском языке, которая доступна здесь. Есть отличный поиск по документации, примеры использования функций, а также прямо на сайте Вы можете почитать рекомендации пользователей PHP по применению конкретных возможностей.

Поддерживаемые на нашем хостинге функции

Мы используем одну из последних версий PHP в виде модуля для веб-сервера Apache, которая собрана с поддержкой следующих модулей (функций):

  • bcmath
  • calendar
  • ctype
  • curl
  • date
  • dba
  • dom
  • ereg
  • filter
  • ftp
  • gd
  • gettext
  • hash
  • iconv
  • imap
  • json
  • libxml
  • mbstring
  • mcrypt
  • mhash
  • mysql
  • mysqli
  • mysqlnd
  • openssl
  • pcre
  • PDO
  • pdo_mysql
  • Reflection
  • session
  • SimpleXML
  • SPL
  • standard
  • tokenizer
  • xml
  • xmlreader
  • xmlwriter
  • xsl
  • zip
  • zlib

Расширения файлов для PHP-скриптов, как добавить свое расширение

Интерпретатором PHP автоматически обрабатываются как PHP-сценарии файлы со следующими расширениями:

  • *.php
  • *.phtml

То есть, файлы, имеющие такие расширения, будут автоматически обрабатываться веб-сервером как PHP-скрипты. Например, index.php или 123.phtml. Пользователь может самостоятельно добавить собственные расширения для обработки соответствующих файлов как PHP-сценариев, поместив в файл .htaccess строку вида:

AddType application/x-httpd-php .ext1 .php3 .html
где ext1, php3 и .html — добавляемые расширения в названии файлов. Например, в данном случае PHP-скриптами будут считаться файлы index.ext1, file.php3 и test.html.

Отправка писем с вложениями при помощи функции mail

Ссылки на готовые примеры скриптов, использующих функцию mail для отправки писем с вложениями, есть в документации на сайте разработчика: LII. Mail Functions.

Авторизованная отправка писем с серверов виртуального UNIX-хостинга

В целях безопасности, на всех серверах виртуального UNIX-хостинга заблокированы исходящие соединения на 25 порт, поэтому необходимо использовать альтернативный номер порта, который нужно уточнить у владельца SMTP-сервера. Если отправка будет осуществляться через наш SMTP-сервер, используйте порт 2525.

Пример авторизованной отправки почты с использованием smtp-сервера.

<?php

 $mhSmtpMail_Server     "smtp.domain.tld";       // Укажите адрес SMTP-сервера
 $mhSmtpMail_Port       "2525";                  // Порт SMTP-сервера.
 $mhSmtpMail_Username   "postmaster@domain.tld"// Имя почтового ящика (пользователя)
 $mhSmtpMail_Password   "password";              // и пароль к нему.
 $mhSmtpMail_From       "Имя отправителя";       // Имя отправителя в поле From

function MailSmtp($to$subject$message$headers)

{

  global $mhSmtpMail_Server$mhSmtpMail_Port$mhSmtpMail_Username$mhSmtpMail_Password;


  $mhSmtpMail_localhost  "localhost";
  $mhSmtpMail_newline    "\r\n";
  $mhSmtpMail_timeout    "30";

  $smtpConnect fsockopen($mhSmtpMail_Server$mhSmtpMail_Port$errno$errstr$mhSmtpMail_timeout);

  $smtpResponse fgets($smtpConnect515);

  if(empty($smtpConnect))
    {
      $output "Failed to connect: $smtpResponse";

      return $output;
    }
  else
    {
      $logArray['connection'] = "Connected: $smtpResponse";
    }
    
  fputs($smtpConnect"HELO $mhSmtpMail_localhost$mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['heloresponse'] = "$smtpResponse";

  fputs($smtpConnect,"AUTH LOGIN" $mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['authrequest'] = "$smtpResponse";

  fputs($smtpConnectbase64_encode($mhSmtpMail_Username) . $mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['authmhSmtpMail_username'] = "$smtpResponse";

  fputs($smtpConnectbase64_encode($mhSmtpMail_Password) . $mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['authmhSmtpMail_password'] = "$smtpResponse";

  fputs($smtpConnect"MAIL FROM: $mhSmtpMail_Username$mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['mailmhSmtpMail_fromresponse'] = "$smtpResponse";

  fputs($smtpConnect"RCPT TO: $to$mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['mailtoresponse'] = "$smtpResponse";

  fputs($smtpConnect"DATA" $mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['data1response'] = "$smtpResponse";

  fputs($smtpConnect"Subject: $subject\r\n$headers\r\n\r\n$message\r\n.\r\n");
  $smtpResponse fgets($smtpConnect515);
  $logArray['data2response'] = "$smtpResponse";

  fputs($smtpConnect,"QUIT" $mhSmtpMail_newline);
  $smtpResponse fgets($smtpConnect515);
  $logArray['quitresponse'] = "$smtpResponse";

}

?>

Скачать пример готового скрипта с функцией MailSmtp(): smtpauth.php.sample

Использовать описанную выше функцию MailSmtp() можно для прямой замены функции mail(). Рассмотрим пример самой простой формы на PHP:

<?

if ($_POST['submit'])

 {

  $to      $_POST['to'];
  $subject $_POST['subj'];
  $message $_POST['msg'];

  
  // Заголовки сообщения, в них определяется кодировка сообщения, поля From, To и т.д.
  $headers "MIME-Version: 1.0\r\n";
  $headers .= "Content-type: text/html; charset=windows-1251\r\n";
  $headers .= "To: $to\r\n";
  $headers .= "From: Имя отправителя <postmaster@domain.tld>";

  
//  mail ($to, $subject, $message, $headers);
 
  require_once "smtpauth.php";
  MailSmtp ($to"=?windows-1251?B?".base64_encode($subject)."?="$message$headers);

}

?>

<form action="" method="post">
  <pre>
    To:   <input type="text" name="to">
    Subj: <input type="text" name="subj">

    Msg:  <input type="text" name="msg">
    <input type="submit" value="Send mail!" name="submit">
  </pre>
</form>

Для того, что бы данная форма заработала без функции mail() мы включили файл smtpauth.php через require_once и вызвали функцию MailSmtp(), описанную в нем, с аналогичными для mail() аргументами. При этом сам вызов mail() мы закомментировали в коде, что бы избежать ошибки при выполнении скрипта.

Отправка писем при помощи функции mail()

В следующим примере мы воспользуемся встроенной функцией mail(), где в качестве параметров, клиентские данные будут переданы посредством $_POST запроса.

<?php
if ($_POST['submit'])
 {
  $from    $_POST['from'];
  $to      $_POST['to'];
  $subject $_POST['subj'];
  $message $_POST['msg'];
  $headers "From: $from\r\n";
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .= "Content-Type: text/plain; charset=windows-1251\r\n"."Content-Transfer-Encoding: 8bit\r\n";
  mail($to"=?windows-1251?B?".base64_encode($subject)."?="$message$headers"-f ".$from);
}
?>

<form action="" method="post">
  <pre>
    From:   <input type="text" name="from">
    To:   <input type="text" name="to">
    Subj: <input type="text" name="subj">
    Msg:  <input type="text" name="msg">
    <input type="submit" value="Send mail!" name="submit">
  </pre>
</form>

Проблемы работы функций strtoupper() и strtolower() с кириллицей

Проблемы при работе с кириллицей в PHP-скриптах функций strtoupper() и strtolower() возникают, когда неправильно определена текущая локаль (locale). Для правильного её определения следует воспользоваться функцией setlocale() в самом начале вашего PHP-сценария:

<?php

setlocale(LC_ALL'ru_RU.CP1251');

echo strtoupper('Работает!');

?>

Поиск с помощью Яндекс.XML

Если Вы решили воспользоваться сервисом Яндекс.XML, то прежде всего вам потребуется выделенный IP-адрес, который Вы можете добавить для любого домена в личном кабинете: в меню Древо услуг > Домен, напротив характеристики «выделенный IP/SSL» нажмите «добавить» (в данном случае подключать SSL не обязательно, но в комментариях обязательно укажите причину, по которой вам понадобился выделенный IP-адрес).

Далее для организации запроса именно с выделенного IP-адреса существует несколько вариантов:

  1. Использовать функцию socket_bind:

    <?php
    // Создаем новый сокет:
    $sock socket_create(AF_INETSOCK_STREAMSOL_TCP);
    // Ваш выделенный IP-адрес:
    $sourceip 'xxx.xxx.xxx.xxx';
    // Используем этот IP-адрес:
    socket_bind($sock$sourceip);
    // Соединяемся с удаленным сервером:
    socket_connect($sock'xmlsearch.yandex.ru'80);
    // Делаем запрос:
    $request 'GET /xmlsearch?query=' $search ' HTTP/1.0' ."\r\n" .'Host: xmlsearch.yandex.ru ' "\r\n\r\n";
    socket_write($sock$request);
    // Получаем и выводим ответ:
    while(!socket_last_error($sock)){
        if($buffer=socket_read($sock,512,PHP_NORMAL_READ)){
            echo $buffer;
            } }
    // Закрываем сокет:
    socket_close($sock);
    ?>

    Здесь переменная $search обозначает только сам поисковый запрос, как это описано на сайте Яндекса, то, что написано после выражения «query=».

  2. C помощью curl_setopt:

    <?php
    $ch curl_init();
       curl_setopt($chCURLOPT_CONNECTTIMEOUT30);
       curl_setopt($chCURLOPT_TIMEOUT30);
       curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
       curl_setopt($chCURLOPT_NOBODYfalse);
       curl_setopt($chCURLOPT_HEADERfalse);
       curl_setopt($chCURLOPT_INTERFACE"xxx.xxx.xxx.xxx");
       curl_setopt($chCURLOPT_URL$search);
       $xml_data=curl_exec($ch);
    curl_close($ch);
    ?>

Переменная $search — HTTP-запрос целиком (то есть URL).

Как измененить версию PHP

При изменении версии PHP, в первую очередь обратите внимание на то, что одна версия PHP распространяется на все размещенные на площадке сайты, поэтому изменить версию можно только для всей площадки, а не для отдельных сайтов. Если необходимо иметь разные версии для размещенных сайтов, то такие сайты нужно разместить на разных площадках.

У Вас будет возможность изменить версию PHP на предыдущую, если Вы не уверены в том, что Ваши сайты будут работать корректно с новой версией PHP. Изменение версии PHP обычно занимает не больше 1 минуты.

Для изменения версии PHP пройдите в личный кабинет https://cp.masterhost.ru, нажмите на пункт меню «Древо услуг» и выберите вашу виртуальную площадку uXXXXX. Далее в списке параметров найдите строчку смена версии ПО и нажмите кнопку изменить, как показано на рисунке.

Как увеличить лимиты: потребление оперативной памяти (memory_limit), время выполнения скрипта (max_execution_time) и т.п.

Лимиты потребления PHP-интерпретатором ресурсов сервера (memory_limit, max_execution_time и т.п.) регулируются тарифным планом площадки виртуального хостинга. Чтобы увеличить такие лимиты, необходимо перейти на следующий по старшинству тарифный план. Ознакомиться с техническими параметрами Вашего тарифного плана можно в Приложении №1.2 к Публичной оферте (Договору), а также на странице с выводом функции phpinfo(), ссылка на которую доступна на странице с характеристиками тарифного плана.

Как собрать свой собственный интерпретатор PHP или внести изменения на уровне компиляции PHP (добавление модулей, изменение системных опций PHP_INI_SYSTEM)

На серверах виртуального хостинга недоступен Си-компилятор, поэтому сборка из исходных кодов собственного PHP-интерпретатора невозможна. Если для работы Вашего проекта требуется нестандартная конфигурация PHP или наличие библиотек, которые отсутствуют в нашей сборке, мы рекомендуем рассмотреть наши услуги по аренде виртуального (VPS) или физического (dedicated) сервера без нашего администрирования. Такой сервер не будет зависеть от конфигурации и ограничений нашей хостинговой среды, и Вы, как администратор сервера, сможете самостоятельно установить и настроить любое необходимое Вашему проекту программное обеспечение.

Также о возможности установки нестандартного ПО на Вашей площадке Вы можете уточнить у наших инженеров службы технической поддержки, отправив письменную заявку "на свободную тему" из Личного кабинета. Возможно, предоставление этого ПО на площадках виртуального хостинга уже находится в наших ближайших планах, или мы сможем установить его для Вас на dediacated сервер с нашим администрированием.

Как изменить значение опций, имеющих статус изменяемости PHP_INI_PERDIR или PHP_INI_ALL

Вы можете изменить некоторые директивны PHP непосредственно в личном кабинете. Для этого перейдите в раздел «Древо услуг» и нажмите на Вашем сайте, для которого нужно изменить настройки PHP. На странице с параметрами размещенного сайта найдите строчку PHP и нажмите изменить, как показано на рисунке.

На открывшейся странице Вам будет доступен интерфейс управления некоторыми настройками PHP-интерпретатора

Если нужной директивы со статусом изменяемости PHP_INI_PERDIR или PHP_INI_ALL нет в списке, Вы можете изменить ее с помощью управляющего файла .htaccess

В следующем примере мы изменим значение директивы mail.log, которая в качестве параметра принимает путь до файла, в который будут записываться все вызовы функции mail() при отправке писем скриптами сайта. Для этого воспользуемся файлом .htaccess, в который нужно добавить всего одну строчку.

php_value mail.log "/home/u12345/phpmail.log"

Теперь все вызовы функции mail() скриптами этого сайта будут записываться в файл phpmail.log в корне площадки u12345. Аналогичным образом можно менять и другие директивы, если их статус изменяемости соответствует PHP_INI_PERDIR или PHP_INI_ALL.

Напомним значение и расшифровку констант PHP_INI_*:

PHP_INI_USER 1 Опция может быть установлена в пользовательских скриптах
PHP_INI_PERDIR 2 Опция может быть установлена в php.ini, .htaccess или httpd.conf
PHP_INI_SYSTEM 4 Опция может быть установлена в php.ini или httpd.conf
PHP_INI_ALL 7 Опция может быть установлена где угодно

Список, описание и статус изменяемости директив можно найти в приложении G документации PHP.

Как выполнять PHP-скрипты в заданное время по расписанию

Иногда у PHP-программистов возникают задачи, которые требуют запуска PHP-скриптов в указанное время. Например, загрузка прайс-листа в базу данных, создание/удаление файлов на диске сервера, загрузка на сервер документов с других серверов и так далее. Можно использовать для этого возможности программы cron, которая работает на сервере.

Подробности о работе cron и его использовании Вы найдете в отдельном документе. Здесь же мы опишем тонкости запуска таким образом именно PHP-скриптов.

На наших серверах установлен бинарный файл интерпретатора PHP, который можно вызывать из cron. Полный путь к нему — /usr/local/bin/php. В качестве параметра нужно передать полный путь до запускаемого PHP-скрипта. Пример задания для cron:

  • в случае с PHP 5 
    0 1 * * * /usr/local/bin/php /home/uXXXXX/script.php
  • или в случае с PHP 4
    0 1 * * * /usr/local/bin/php /home/uXXXXX/script.php

В данном примере скрипт, который находится на диске сервера и имеет полный путь /home/uXXXXX/script.php, запускается в 1 час ночи каждый день. Не забывайте нажимать Enter после каждой строки в cron — все строки в сценариях cron должны заканчиваться переводом строки или задание работать не будет.

Вывод ошибок в PHP

Иногда возникает необходимость получить информацию о том, какие ошибки возникают при выполнении PHP-скриптов. При использовании PHP как модуля Apache (по умолчанию именно так) вывод ошибок доступен в личном кабинете в меню Древо услуг в разделе Домен domain.tld, где domain.tld — имя вашего домена, далее характеристика HTTP > error_log.

Иногда имеет смысл включить вывод ошибок PHP-скриптов на экран. Возможно 2 случая:

  1. Если Вы используйте PHP-интерпретатор как модуль Apache, создайте в той директории, где находятся скрипты, файл .htaccess (если он не существует) и добавьте 2 строки, одна из которых включает вывод ошибок в браузер, а вторая определяет уровень отображаемых ошибок:

    php_flag display_errors on
    php_value error_reporting 2047

    Число 2047 является значением константы E_ALL и включает вывод всех типов ошибок. Значение константы E_ALL зависит от версии PHP. Точное значение можно узнать на сайте разработчика.

  2. Если Вы используете PHP-интерпретатор как CGI, то для вывода ошибок следует в файле настроек для PHP, изменить значение параметра

    display_errors = Off
    на 
    display_errors = On

    Кроме этого, надо изменить значение параметра error_reporting со значения E_ALL & E_NOTICE на простое E_ALL (по желанию).

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

Ограничения

Нужно учитывать, что на работу PHP налагаются некоторые ограничения. По соображениям безопасности мы запретили использование следующих команд:

  • dl
  • shell_exec
  • exec
  • system
  • passthru
  • popen
  • proc_open
  • proc_nice
  • proc_get_status
  • proc_close
  • proc_terminate
  • posix_mkfifo
  • set_time_limit
  • chown
  • chgrp
  • accelerator_reset
  • opcache_reset
  • accelerator_get_status
  • opcache_get_status
  • pcntl_alarm
  • pcntl_fork
  • pcntl_waitpid
  • pcntl_wait
  • pcntl_wifexited
  • pcntl_wifstopped
  • pcntl_wifsignaled
  • pcntl_wexitstatus
  • pcntl_wtermsig
  • pcntl_wstopsig
  • pcntl_signal
  • pcntl_signal_dispatch
  • pcntl_get_last_error
  • pcntl_strerror
  • pcntl_sigprocmask
  • pcntl_sigwaitinfo
  • pcntl_sigtimedwait
  • pcntl_exec
  • pcntl_getpriority
  • pcntl_setpriority
Если на самом деле Вы хотите использовать функции вроде exec для выполнения периодических заданий вроде бэкапа баз MySQL, пожалуйста, используйте для этого cron. Если же нужно разово выполнить какую-то команду, можно использовать для этого UNIX shell.

В помощь вам мы приводим ссылки на полезные ресурсы по тематике PHP: