Безгрешен php сървър. Каква е разликата между HTTP_HOST и SERVER_NAME в PHP? Пълен URL адрес на скрипта

Безгрешен php сървър.  Каква е разликата между HTTP_HOST и SERVER_NAME в PHP?  Пълен URL адрес на скрипта
Безгрешен php сървър. Каква е разликата между HTTP_HOST и SERVER_NAME в PHP? Пълен URL адрес на скрипта

$HTTP_SERVER_VARS [премахнато]

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

$_SERVER -- $HTTP_SERVER_VARS [премахнато]Информация за сървъра и времето за изпълнение

Описание

Променливата $_SERVER е масив, съдържащ информация като заглавки на скриптове, пътища и местоположения. Записите в този масив се създават от уеб сървъра. Няма гаранция, че всеки уеб сървър ще предостави някое от тези; сървърът може да пропусне някои от тях или да предостави други, които не са изброени тук. Много от тези променливи обаче присъстват в спецификацията » CGI/1.1, така че можете да очаквате да бъдат внедрени и в конкретен уеб сървър.

Променливата $HTTP_SERVER_VARS съдържа същата първоначална информация, но не е суперглобална. (Имайте предвид, че $HTTP_SERVER_VARS и $_SERVER са различни променливи, така че PHP ги обработва по съответния начин.) Също така имайте предвид, че „дългите масиви“ бяха премахнати в PHP 5.4.0, така че $HTTP_SERVER_VARS вече не съществува.

Индекси

Може да намерите или да не намерите някой от следните елементи в масива $_SERVER. Имайте предвид, че малко, ако има такива, елементи ще бъдат налични (или наистина имат значение), ако PHP се изпълнява от командния ред.

„PHP_SELF“ Името на файла на скрипта, който се изпълнява в момента, спрямо корена на документа. Например $_SERVER["PHP_SELF"] в скрипт на http://example.com/foo/bar.php ще бъде /foo/bar.php. Константата __FILE__ съдържа пълен пъти името на текущия (т.е. свързан) файл. Ако PHP се изпълнява от командния ред, тази променлива съдържа името на скрипта от PHP 4.3.0. Преди това не беше налице."argv" Масив от аргументи, предадени на скрипта. Когато скриптът се изпълнява от командния ред, той дава подобен на C достъп до опциите командна линия. Когато се извика чрез метода GET, този масив ще съдържа низа на заявката."argc" Съдържа броя на параметрите, предадени на скрипта (ако е стартиран от командния ред).„GATEWAY_INTERFACE“ Съдържа версията на CGI спецификацията, използвана от сървъра; Например" CGI/1.1". „SERVER_ADDR“ IP адресът на сървъра, където се изпълнява текущият скрипт."ИМЕ НА СЪРВЪРА" Името на хоста, където се изпълнява текущият скрипт. Ако скриптът се изпълнява на виртуален хост, това ще съдържа името, дефинирано за него виртуален хост. "SERVER_SOFTWARE" Идентификационният низ на сървъра, посочен в заглавките, когато се отговори на заявката."SERVER_PROTOCOL" Името и версията на информационния протокол, чрез който е заявена страницата; Например " HTTP/1.0"; „REQUEST_METHOD“ Какъв метод е използван за заявка на страницата; Например " ВЗЕМЕТЕ", "ГЛАВА", "ПУБЛИКУВАНЕ", "СЛАГАМ".

Коментирайте:

PHP скриптът прекратява след изпращане на заглавки (т.е. след като направи някакъв изход без буфериране на изход), ако заявката е направена от метода ГЛАВА.

„REQUEST_TIME“ Времево клеймо на началото на заявката. Предлага се от PHP 5.1.0.„REQUEST_TIME_FLOAT“ Часовото клеймо на началото на заявката, с точност до микросекунди. Предлага се от PHP 5.4.0.„QUERY_STRING“ Низът на заявката, ако има такъв, с който страницата е извлечена.„DOCUMENT_ROOT“ Основната директория на документа, където се изпълнява текущият скрипт, е точно тази, посочена в конфигурационен файлсървър."HTTP_ACCEPT" Съдържание на заглавката приемам:от текущата заявка, ако има такава."HTTP_ACCEPT_CHARSET" Съдържание на заглавката AcceptCharset:от текущата заявка, ако има такава. Например: " iso-8859-1,*,utf-8". "HTTP_ACCEPT_ENCODING" Съдържание на заглавката Приемане на кодиране: gzip". "HTTP_ACCEPT_LANGUAGE" Съдържание на заглавката Език за приемане:от текущата заявка, ако има такава. Например: " en". "HTTP_CONNECTION" Съдържание на заглавката Връзка:от текущата заявка, ако има такава. Например: " Запази живи". "HTTP_HOST" Съдържание на заглавката домакин:от текущата заявка, ако има такава."HTTP_REFERER" Адресът на страницата (ако има такава), която е довела браузъра на потребителя до тази страница. Тази заглавка се задава от уеб браузъра на потребителя. Не всички браузъри го инсталират, а някои позволяват промяна на съдържанието на заглавката HTTP_REFERER като допълнителна функция. С една дума, наистина не може да му се вярва."HTTP_USER_AGENT" Съдържание на заглавката Потребителски агент:от текущата заявка, ако има такава. Този низ съдържа обозначението на браузъра, който потребителят е поискал тази страница. Типичен пример е редът: Mozilla/4.5 (X11; U; Linux 2.2.9 i586). Освен всичко друго, можете да използвате тази стойност с функцията get_browser()за да приспособите изхода на вашата страница към възможностите на браузъра на потребителя"https" Приема непразна стойност, ако заявката е направена чрез HTTPS протокол.

Коментирайте: Имайте предвид, че когато използвате ISAPI с IIS, стойността ще бъде изключеноако заявката не е направена чрез HTTPS протокол.

„REMOTE_ADDR“ IP адресът, от който потребителят разглежда текущата страница.„REMOTE_HOST“ Отдалеченият хост, от който потребителят разглежда текущата страница. Обратното DNS търсене се базира на стойността на променливата REMOTE_ADDR.

Коментирайте: Вашият уеб сървър трябва да е конфигуриран да създава тази променлива. Например в Apache се нуждаете от наличието на директивата Търсенето на име на хост е включеновъв файла httpd.conf, за да бъде създадена тази променлива. Вижте също gethostbyaddr().

„REMOTE_PORT“ Портът на отдалечената машина, който се използва за комуникация с уеб сървъра.„REMOTE_USER“ Удостовереният потребител.„REDIRECT_REMOTE_USER“ Удостовереният потребител, ако заявката е пренасочена вътрешно.„SCRIPT_FILENAME“

Абсолютният път към сценария, който този моментсе изпълнява.

Коментирайте:

Ако скриптът се изпълнява на командния ред (CLI), като се използва относителен път като file.php или ../file.php, променливата $_SERVER["SCRIPT_FILENAME"] ще съдържа относителния път, зададен от потребителя.

„SERVER_ADMIN“ Тази променлива получава своята стойност (за Apache) от директива в конфигурационния файл на сървъра. Ако скриптът се изпълнява на виртуален хост, това ще бъде стойността, дефинирана за този виртуален хост."SERVER_PORT" Портът на сървърния компютър, който уеб сървърът използва за свързване. За настройките по подразбиране стойността ще бъде " 80 "; използвайки SLL, например, тази стойност ще бъде както е конфигурирана за защитени HTTP връзки.

Коментирайте: За да получите физически (реален) порт в Apache 2, трябва да инсталирате UseCanonicalName = ВклИ UseCanonicalPhysicalPort = Вкл, в противен случай тази стойност може да бъде подправена и да не върне реалната стойност на физическия порт. Разчитането на тази стойност не е безопасно в контекста на приложения, които изискват повишена сигурност.

„SERVER_SIGNATURE“ Низ, съдържащ версията на сървъра и името на виртуалния хост, които да бъдат добавени към генерираните от сървъра страници, ако е разрешено.„PATH_TRANSLATED“ Път до текущия скрипт, базиран на файловата система (не на основния документ), след като сървърът е извършил преобразуване от виртуално към реално.

Коментирайте: От PHP 4.3.2, променливата PATH_TRANSLATED вече не е имплицитно зададена в Apache 2 SAPI, в сравнение с Apache версия 1, където е зададена същата стойност като SCRIPT_FILENAME, когато не се използва от Apache. Тази промяна е направена, за да се съобрази със спецификацията на CGI, където променливата PATH_TRANSLATED трябва да съществува само когато е дефиниран PATH_INFO. Потребителите на Apache 2 могат да използват директивата AcceptPathInfo = Вклв конфигурационния файл httpd.conf, за да зададете променливата PATH_INFO.

„SCRIPT_NAME“ Съдържа пътя до текущо изпълняващия се скрипт. Това е полезно за страници, които трябва да сочат към себе си. Константата __FILE__ съдържа пълния път и името на текущия (т.е. включен) файл.„REQUEST_URI“ URI адресът, който беше предаден за достъп до тази страница. Например, " /index.html". „PHP_AUTH_DIGEST“ Когато извършвате HTTP Digest удостоверяване, тази променлива е зададена на заглавката „Authorization“, изпратена от клиента (която след това трябва да се използва за подходящо валидиране).„PHP_AUTH_USER“ Когато се извършва HTTP удостоверяване, тази променлива се задава на потребителското име, предоставено от потребителя.„PHP_AUTH_PW“ Когато се извършва HTTP удостоверяване, тази променлива се задава на паролата, предоставена от потребителя.„AUTH_TYPE“ Когато се извършва HTTP удостоверяване, тази променлива е зададена на вида на използваното удостоверяване.„PATH_INFO“ Съдържа всеки предоставен от потребителя път след името на скрипта, но преди низа на заявката, ако е наличен. Например, ако текущият скрипт е заявен на URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, тогава променливата $_SERVER["PATH_INFO"] ще съдържа /някои неща?>

Резултатът от изпълнението на този пример ще бъде нещо подобно.

  • Превод
  • урок

Една от най-готините нови функции в php 5.4 е вграден сървър, създаден специално за разработка и тестване. Сега можете да пишете и тествате кода си, без да имате пълен уеб сървър - просто стартирайте вградения сървър, тествайте кода си и го изключете, когато сте готови.
Сървърът предоставя и възможност за творческо използване. Например, можете да разпространявате преносимо уеб приложение на CD или USB, или дори като настолно приложение, изградено в PHP, без използването на GTK или други графични библиотеки.

Ръководството за PHP подчертава, че вграденият сървър е за разработка и препоръчва да не се използва на производствен сървър. Няма INI директиви, отговарящи за сървъра (с изключение на оцветяването на изхода в конзолата) и изглежда, че основната идея на документацията е: „сега също имаме уеб сървърмахни се от нас."
Въпреки това вярвам, че вграденият сървър може да бъде ценен инструмент за разработка и тестване. Например на моята машина използвам предварително инсталирания Apache с персонализирана конфигурация, която работи за мен, но понякога искам да опитам някои нови уеб приложения. С вградения уеб сървър мога да тествам приложението директно от папката "изтегляния" или временната папка и да го преместя в нормалната среда само когато е необходимо.
Но като за начало не е толкова лесно, защото много приложения са написани с помощта на .htaccess и mod_rewrite. Но съм сигурен, че някой (може би един от вас, защо не?) ще напише адаптер за това и бих искал да съм първият, който ще го тества.
В тази статия ще обясня някои основни случаи на използване на вградения сървър и ще ви покажа как да го направите полезен за разработка и тестване.

Използваме вградения сървър

Така че, за да използваме сървъра, се нуждаем от php 5.4 или по-нова версия. За да проверите версията на PHP, изпълнете:
php -v
Можете също така да определите дали сървърът е наличен във вашата компилация, като изпълните:
php -h
и потърсете там описание на опциите "-S" и "-t", които се използват само за сървъра.
За да тествате сървъра, можете да създадете файл index.php в текущата директория, който ще съдържа извикване на функцията phpinfo() и след това да стартирате сървъра:
$ php -S 127.0.0.1:8080 Сървърът за разработка на PHP 5.4.0RC7 стартира в петък, 26 февруари 18:49:29 2012 г. Слушане на 127.0.0.1:8080 Основният документ е /home/ec2-user Натиснете Ctrl-C, за да излезете.
И сега можете да видите съдържанието, върнато от вградения уеб сървър:

Всяка клиентска заявка ще бъде написана на конзолата:
80.180.55.37:36318 : / 80.180.55.37:36584 : /
Връщайки се назад, нека да разгледаме опцията на командния ред "-S", която се използва за указване на адреса, от който сървърът ще бъде достъпен. Възможни стойности:
локален хост- сървърът ще бъде достъпен само от локалната машина,
0.0.0.0 - на всеки машинен интерфейс,
Всеки външен или сив IP- само на посочения IP
Опцията "-t" задава определената директория на "директория корен". Например:
$ php -S :8090 -t /home/ec2-user/public
Освен това,. можете да посочите името на конкретен файл на рутера. Например:
$ php -S >localhost или вашия публичен IP>:8080 -t /home/ec2-user/public public/index.php
Резултатът от този рутер ще бъде анализиран и изпълнен от сървъра. Прост пример:
Добре дошли в PHP

";
Ако скриптът върне FALSE, тогава исканият URI ще бъде обработен от сървъра, който ще издаде искания ресурс или ще върне грешка 404. Ако скриптът върне нещо друго, изходът от скрипта ще бъде пренасочен към клиента.
Въпреки че този подход ни дава повече контрол, има няколко неща, които трябва да знаете. Първо, PHP сървърът връща само минимален набор от HTTP заглавки:
Връзка: затворена Content-Type: text/html Хост: aws-dev-01.vtardia.com X-Powered-By: PHP/5.4.0RC7 D
Сравнете това със заглавките, върнати от Apache:
Accept-Ranges: bytes Connection: Keep-Alive Content-Length: 631 Content-Type: text/html Date: Sat, 04 Feb 2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout= 15, max=100 Последна промяна: сряда, 14 септември 2011 г. 15:54:09 GMT Сървър: Apache/2.2.21 (Unix) DAV/2
Ако вашето приложение използва заглавки, то трябва да вземе предвид разликата в средата за разработка и в производството.
Второ, вграденият сървър има различен SAPI (API на сървъра). По този начин, чрез извършване на маршрутизиране в index,php, можете да определите дали даден скрипт е достъпен на тестов или производствен сървър. php_sapi_name() ще върне "cli-server" на вграден сървър:
Има една специална INI директива - "cli_server.color". Тази директива връща оцветен изход в конзолата. Създайте празен файл с име cli-server.iniи поставете този ред:
cli_server.color=вкл
Можете да създадете уникална конфигурация на средата за вашия сървър, като посочите необходимите директиви във вашия INI файл. Недекларираните директиви ще приемат стойностите по подразбиране. Сега сме декларирали само една директива - cli_server.color.
Стартирайте сървъра с опцията "-c", като посочите INI файла:
$ php -S localhost -c cli-server.ini
Ако вашият терминал поддържа цветове, тогава ще можете да видите "цветен" изход в конзолата. Състояние 200 ще бъде подчертано в зелено, състояние 404 ще бъде оранжево, а грешките в скрипта ще бъдат подчертани в червено.

Създаваме личен сървър

След като вече знаете всичко, което трябва да знаете за вградения сървър, нека направим нещо страхотно. Нека създадем наш собствен преносим сървър!
Ще започна със следната структура за нашето приложение:

Папката "library" съдържа кода на приложението, "public" - основната директория, съдържа index.php и няколко статични файла. Акцентът в този урок ще бъде върху папката "server", така че нашето приложение ще се състои от просто "Hello Word!" и някои изображения и css.
Нашата цел е да можем да стартираме сървъра от директорията на приложението с една команда, а нашият сървър ще се погрижи за маршрутизирането, HTTP заглавките и грешките.
$ ./start.sh
Нека да разгледаме скрипта за стартиране:
#! /bin/bash INIFILE="$(pwd)/server/server.ini" DOCROOT="$(pwd)/public" ROUTER="$(pwd)/server/router.php" HOST=0.0.0.0 PORT=8080 PHP=$(кой php) ако [ $? != 0] ; след това echo "Не може да се намери PHP" изход 1 fi $PHP -S $HOST:$PORT -c $INIFILE -t $DOCROOT $ROUTER
Предполагам, че скриптът се изпълнява от директорията на приложението, така че INIFILE, DOCROOT, ROUTER се дефинират с помощта на pwd. Пътят до php се определя с помощта на командата which. Ако php не е намерен в $PATH на потребителя, тогава скриптът ще се провали с грешка.
Този метод работи доста добре, но нека дадем на потребителя възможността да промени някоя от дадените опции от командния ред, например:
ако [! -z $INFILE]; тогава INIFILE="$(pwd)/server/server.ini" fi
Продължавайки, папката "грешки" съдържа файлове за HTTP съобщения за грешки. Ето пример за грешка 403: въпреки че използвах само HTML, скриптът ще бъде включен, използвайте включваттака че можете да използвате всеки php код:
403

403: Забранено

За съжаление исканият ресурс не е достъпен.

Сега нека да разгледаме router.php. Целта на този файл е да получава и управлява всички заявки и да ги предава на сървъра само ако този файл съществува. Всички страници с грешки се изобразяват чрез свързване на шаблон.
В първите редове дефинирам някои глобални опции, като DIRECTORY_INDEX, директорията с шаблони за грешки. Параметърът date_default_timezone_set() трябва да съответства на настройките на ОС, в противен случай ще има несъответствия между записите в дневника и на сървъра. Добавих също списък с разрешени IP адреси, за да подобря сигурността.
Функцията logAccess() е необходима, защото когато скриптът за маршрутизиране получи заявка, регистрационният файл на сървъра по подразбиране се игнорира. Функцията приема само код на състоянието, а изходният формат е напълно съвместим с формата на сървъра.
Първата ни задача е проверка за сигурност. Ако IP адресът на клиента не е в разрешения IP масив, показваме съобщение за грешка и излизаме от скрипта. Трябва да върнем код на състояние, различен от 200 и функцията header() няма да работи тук, така че използваме нова функция - http_response_code.
Ако IP адресът на клиента е в разрешения IP масив, тогава следващата ни стъпка е да получим искания път и файлово разширение. Ако разширението е празно, приемаме, че потребителят иска папка и изграждаме пътя, използвайки DIRECTORY_INDEX, дефиниран първо.
И накрая, ако исканият файл съществува, върнете FALSE и оставете сървъра да получи достъп до файла. В противен случай се показва съобщение за грешка 404.

Резюме

Това е всичко. Както можете да видите, php сървърът е лесен за използване. Нашият личен сървър е много прост. Кодът може да бъде оптимизиран и включен в по-сложни и функционални класове. щастливо кодиране!

p.s. С радост приемам критики и коментари по превода на лични.

$_SERVERе един от най-важните предварително дефинирани масиви в PHP. PHP интерпретаторът съдържа променливите, получени от сървъра в него. Всички са използвали тези променливи или определено ще ги използват, защото без тях е доста трудно да се организира пълноценна поддръжка за уеб приложения.

В моята статия предлагам таблица с основните променливи на суперглобалния масив $_SERVER. Таблицата е подобна на тази, направена за низовите функции на PHP.

За да видите всички елементи на масива $_SERVER, трябва: а) или да извикате функцията print_r(), която ще отпечата масива; б) или извикайте функцията phpinfo(), която ще покаже информация за PHP интерпретатора.

Накратко за $HTTP_SERVER_VARS

Суперглобалният масив $_SERVER замени масива $HTTP_SERVER_VARS в PHP версия 4.1.0. $HTTP_SERVER_VARSне се използва сега, но си струва да знаете за него. Първо, старата версия не беше автоматично глобална. Втората разлика е, че някои елементи от масива $_SERVER не съществуват в $HTTP_SERVER_VARS, въпреки че в повечето случаи техните променливи са еднакви.

елемент

Кратко описание

Пример

$_SERVER["DOCUMENT_ROOT"]

Съдържа пътя до основната директория на сървъра.

$_SERVER["HTTP_HOST"]

$_SERVER["SERVER_NAME"]

$_SERVER["SCRIPT_FILENAME"]

Съдържа името на скрипта, започвайки от основната директория на виртуалния хост.

C:\папка\index.php

/www/папка/index.php

$_SERVER["PHP_SELF"]

$_SERVER["SCRIPT_NAME"]

Съдържа името на скрипта.

$_SERVER["REQUEST_URI"]

Съдържа името на скрипта, започвайки от основната директория на виртуалния хост, както и параметрите, предадени му чрез метода GET.

/www/folder/index.php?page=2&num=5

$_SERVER["QUERY_STRING"]

Съдържа параметри, предадени на скрипта чрез метода GET.

За адрес

http://site.com/index.php?page=2&num=5

ще се покаже

$_SERVER["REQUEST_METHOD"]

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

ВЗЕМЕТЕ илиПУБЛИКУВАНЕ

$_SERVER["HTTP_REFERER"]

Съдържа адреса на страницата, от която е дошъл посетителят.

http://yandex.ru/yandsearch

$_SERVER["HTTP_USER_AGENT"]

Съдържа вида и версията на браузъра и операционната система на посетителя. Може също да идентифицира роботите за търсене и марката на мобилния телефон. По-долу е сравнение на марката на телефона и неговия код в низа.

Nokia-NOKIA; Sony Ericsson - ERICSSON или SONYERICSSON; Samsung - SAMSUNG или SEC-; Motorola-MOT; LG - LG или LG-; Alcatel - ALCATEL; Панасоник - PANASONIC; Sagem-SAGEM; Пантех - PANTECH; Siemens-SIE; BenQ-BENQ; NEC - НЕК; Sharp-SHARP.

Mozilla/4.0 (съвместим; MSIE 6.0; Windows NT 5.1) ( IE6ИУиндоус експи)

Mozilla/4.0 (съвместим; MSIE 7.0; Windows NT 5.0) Opera 9.50 ( Opera 9.5ИWindows 2000)

$_SERVER["REMOTE_ADDR"]

Съдържа IP адреса на клиента.

$_SERVER["SERVER_ADDR"]

Съдържа IP адреса на сървъра.

$_SERVER["HTTP_ACCEPT"]

Описва предпочитанията на клиента относно вида на документа. Съдържанието на този елемент се извлича от заглавката Accept HTTP, която се предава на сървъра от клиента.

Изходен формат: MIME тип [[; q], друг тип MIME [; р] ... ]

Може да има няколко предпочитани типа MIME, като в този случай те са изброени разделени със запетаи. * се използва за задаване на модел, групиране. q – фактор на предпочитание, по подразбиране 1, варира от 0 до 1.

изображение/jpeg, изображение/x-xbitmap, приложение/x-shockwave-flash

изображение/*; q=0,5, изображение/jpeg (предпочита jpeg пред всички останали формати)

$_SERVER["HTTP_ACCEPT_LANGUAGE"]

Подобен на предишния елемент, но вече свързан с езиковите предпочитания. Може да се използва за определяне на националността на посетителите. Но оценката ще бъде приблизителна, защото някои хора обичат да използват английски версии на браузъри

ru, en; q=0,9 (предпочитание за руски, но ако не е там, английски ще свърши работа)

$_SERVER["HTTP_ACCEPT_CHARSET"]

Подобни на предишните. Съдържа заглавката Accept-Charset

$_SERVER["HTTP_ACCEPT_ENCODING"]

Подобни на предишните. Съдържа заглавката Accept-Encoding

$_SERVER["SERVER_PORT"]

Съдържа слушащия порт на сървъра.

$_SERVER["SERVER_SOFTWARE"]

Съдържа информация за уеб сървъра.

Apache/2.2.4 (Win32)

$_SERVER["SERVER_PROTOCOL"]

Съдържа версията на HTTP протокола.

$_SERVER["GATEWAY_INTERFACE"]

Съдържа CGI версията, използвана от уеб сървъра.

$_SERVER["REQUEST_TIME"]

Началният час на заявката за уеб страница във формат UNIX. Предлага се от PHP 5.1.0

Пълен адрес на страницата с параметри:

echo "http://".SERVER_NAME.$_SERVER["REQUEST_URI"];
?>

Таблица с всички функции можете да изтеглите от линка във формат *.doc.

Обърнете специално внимание на променливата $_SERVER["REQUEST_URI"] и не забравяйте да я проверите!Факт е, че използването му може да не е особено безопасно. Например, някои URL адреси на вашия сайт се генерират с помощта на този параметър. След това можете да напишете в реда на браузъра връзката http://site.com/index.php?”>. В резултат на това ще се покаже прозорец, показващ съдържанието на файла с бисквитките. Този пример е безвреден, но е дупка, през която хакер може да използва пробива, например, за да открадне данните на друг потребител. Затова - проверете променливата за невалидни символи и особено > и<.

За днес може би всичко. До скоро и страхотен уикенд!

  • Превод
  • урок

Една от най-готините нови функции в php 5.4 е вграден сървър, създаден специално за разработка и тестване. Сега можете да пишете и тествате кода си, без да имате пълен уеб сървър - просто стартирайте вградения сървър, тествайте кода си и го изключете, когато сте готови.
Сървърът предоставя и възможност за творческо използване. Например, можете да разпространявате преносимо уеб приложение на CD или USB, или дори като настолно приложение, изградено в PHP, без използването на GTK или други графични библиотеки.

Ръководството за PHP подчертава, че вграденият сървър е за разработка и препоръчва да не се използва на производствен сървър. Няма INI директиви, отговарящи за сървъра (с изключение на оцветяването на изхода в конзолата) и изглежда, че основната идея на документацията е: „вече имаме и уеб сървър, оставете ни на мира ."
Въпреки това вярвам, че вграденият сървър може да бъде ценен инструмент за разработка и тестване. Например на моята машина използвам предварително инсталирания Apache с персонализирана конфигурация, която работи за мен, но понякога искам да опитам някои нови уеб приложения. С вградения уеб сървър мога да тествам приложението директно от папката "изтегляния" или временната папка и да го преместя в нормалната среда само когато е необходимо.
Но като за начало не е толкова лесно, защото много приложения са написани с помощта на .htaccess и mod_rewrite. Но съм сигурен, че някой (може би един от вас, защо не?) ще напише адаптер за това и бих искал да съм първият, който ще го тества.
В тази статия ще обясня някои основни случаи на използване на вградения сървър и ще ви покажа как да го направите полезен за разработка и тестване.

Използваме вградения сървър

Така че, за да използваме сървъра, се нуждаем от php 5.4 или по-нова версия. За да проверите версията на PHP, изпълнете:
php -v
Можете също така да определите дали сървърът е наличен във вашата компилация, като изпълните:
php -h
и потърсете там описание на опциите "-S" и "-t", които се използват само за сървъра.
За да тествате сървъра, можете да създадете файл index.php в текущата директория, който ще съдържа извикване на функцията phpinfo() и след това да стартирате сървъра:
$ php -S 127.0.0.1:8080 Сървърът за разработка на PHP 5.4.0RC7 стартира в петък, 26 февруари 18:49:29 2012 г. Слушане на 127.0.0.1:8080 Основният документ е /home/ec2-user Натиснете Ctrl-C, за да излезете.
И сега можете да видите съдържанието, върнато от вградения уеб сървър:

Всяка клиентска заявка ще бъде написана на конзолата:
80.180.55.37:36318 : / 80.180.55.37:36584 : /
Връщайки се назад, нека да разгледаме опцията на командния ред "-S", която се използва за указване на адреса, от който сървърът ще бъде достъпен. Възможни стойности:
локален хост- сървърът ще бъде достъпен само от локалната машина,
0.0.0.0 - на всеки машинен интерфейс,
Всеки външен или сив IP- само на посочения IP
Опцията "-t" задава определената директория на "директория корен". Например:
$ php -S :8090 -t /home/ec2-user/public
Освен това,. можете да посочите името на конкретен файл на рутера. Например:
$ php -S >localhost или вашия публичен IP>:8080 -t /home/ec2-user/public public/index.php
Резултатът от този рутер ще бъде анализиран и изпълнен от сървъра. Прост пример:
Добре дошли в PHP

";
Ако скриптът върне FALSE, тогава исканият URI ще бъде обработен от сървъра, който ще издаде искания ресурс или ще върне грешка 404. Ако скриптът върне нещо друго, изходът от скрипта ще бъде пренасочен към клиента.
Въпреки че този подход ни дава повече контрол, има няколко неща, които трябва да знаете. Първо, PHP сървърът връща само минимален набор от HTTP заглавки:
Връзка: затворена Content-Type: text/html Хост: aws-dev-01.vtardia.com X-Powered-By: PHP/5.4.0RC7 D
Сравнете това със заглавките, върнати от Apache:
Accept-Ranges: bytes Connection: Keep-Alive Content-Length: 631 Content-Type: text/html Date: Sat, 04 Feb 2012 18:24:42 GMT Etag: "bbb99-277-4ace8c5470a40" Keep-Alive: timeout= 15, max=100 Последна промяна: сряда, 14 септември 2011 г. 15:54:09 GMT Сървър: Apache/2.2.21 (Unix) DAV/2
Ако вашето приложение използва заглавки, то трябва да вземе предвид разликата в средата за разработка и в производството.
Второ, вграденият сървър има различен SAPI (API на сървъра). По този начин, чрез извършване на маршрутизиране в index,php, можете да определите дали даден скрипт е достъпен на тестов или производствен сървър. php_sapi_name() ще върне "cli-server" на вграден сървър:
Има една специална INI директива - "cli_server.color". Тази директива връща оцветен изход в конзолата. Създайте празен файл с име cli-server.iniи поставете този ред:
cli_server.color=вкл
Можете да създадете уникална конфигурация на средата за вашия сървър, като посочите необходимите директиви във вашия INI файл. Недекларираните директиви ще приемат стойностите по подразбиране. Сега сме декларирали само една директива - cli_server.color.
Стартирайте сървъра с опцията "-c", като посочите INI файла:
$ php -S localhost -c cli-server.ini
Ако вашият терминал поддържа цветове, тогава ще можете да видите "цветен" изход в конзолата. Състояние 200 ще бъде подчертано в зелено, състояние 404 ще бъде оранжево, а грешките в скрипта ще бъдат подчертани в червено.

Създаваме личен сървър

След като вече знаете всичко, което трябва да знаете за вградения сървър, нека направим нещо страхотно. Нека създадем наш собствен преносим сървър!
Ще започна със следната структура за нашето приложение:

Папката "library" съдържа кода на приложението, "public" - основната директория, съдържа index.php и няколко статични файла. Акцентът в този урок ще бъде върху папката "server", така че нашето приложение ще се състои от просто "Hello Word!" и някои изображения и css.
Нашата цел е да можем да стартираме сървъра от директорията на приложението с една команда, а нашият сървър ще се погрижи за маршрутизирането, HTTP заглавките и грешките.
$ ./start.sh
Нека да разгледаме скрипта за стартиране:
#! /bin/bash INIFILE="$(pwd)/server/server.ini" DOCROOT="$(pwd)/public" ROUTER="$(pwd)/server/router.php" HOST=0.0.0.0 PORT=8080 PHP=$(кой php) ако [ $? != 0] ; след това echo "Не може да се намери PHP" изход 1 fi $PHP -S $HOST:$PORT -c $INIFILE -t $DOCROOT $ROUTER
Предполагам, че скриптът се изпълнява от директорията на приложението, така че INIFILE, DOCROOT, ROUTER се дефинират с помощта на pwd. Пътят до php се определя с помощта на командата which. Ако php не е намерен в $PATH на потребителя, тогава скриптът ще се провали с грешка.
Този метод работи доста добре, но нека дадем на потребителя възможността да промени някоя от дадените опции от командния ред, например:
ако [! -z $INFILE]; тогава INIFILE="$(pwd)/server/server.ini" fi
Продължавайки, папката "грешки" съдържа файлове за HTTP съобщения за грешки. Ето пример за грешка 403: въпреки че използвах само HTML, скриптът ще бъде включен, използвайте включваттака че можете да използвате всеки php код:
403

403: Забранено

За съжаление исканият ресурс не е достъпен.

Сега нека да разгледаме router.php. Целта на този файл е да получава и управлява всички заявки и да ги предава на сървъра само ако този файл съществува. Всички страници с грешки се изобразяват чрез свързване на шаблон.
В първите редове дефинирам някои глобални опции, като DIRECTORY_INDEX, директорията с шаблони за грешки. Параметърът date_default_timezone_set() трябва да съответства на настройките на ОС, в противен случай ще има несъответствия между записите в дневника и на сървъра. Добавих също списък с разрешени IP адреси, за да подобря сигурността.
Функцията logAccess() е необходима, защото когато скриптът за маршрутизиране получи заявка, регистрационният файл на сървъра по подразбиране се игнорира. Функцията приема само код на състоянието, а изходният формат е напълно съвместим с формата на сървъра.
Първата ни задача е проверка за сигурност. Ако IP адресът на клиента не е в разрешения IP масив, показваме съобщение за грешка и излизаме от скрипта. Трябва да върнем код на състояние, различен от 200 и функцията header() няма да работи тук, така че използваме нова функция - http_response_code.
Ако IP адресът на клиента е в разрешения IP масив, тогава следващата ни стъпка е да получим искания път и файлово разширение. Ако разширението е празно, приемаме, че потребителят иска папка и изграждаме пътя, използвайки DIRECTORY_INDEX, дефиниран първо.
И накрая, ако исканият файл съществува, върнете FALSE и оставете сървъра да получи достъп до файла. В противен случай се показва съобщение за грешка 404.

Резюме

Това е всичко. Както можете да видите, php сървърът е лесен за използване. Нашият личен сървър е много прост. Кодът може да бъде оптимизиран и включен в по-сложни и функционални класове. щастливо кодиране!

p.s. С радост приемам критики и коментари по превода на лични.

Като начало ще подобрим страницата за регистрация, като добавим възможност за качване на аватар. Изходното изображение трябва да е във формат jpg, gif или png. Също така не трябва да е повече от 2 MB. Не се притеснявайте, след като го компресирате със скрипта, размерът на аватара ще бъде около 3 kb, а форматът ще бъде jpg. Отворена страница рег.phpи добавете в етикета < форма> линия enctype="multipart/form data", както в примера:


Регистрация










Сега запазете reg.php

2. След това трябва да създадете друго поле в таблицата потребители. Отиваме на phpmyadmin, изберете желаната база данни и таблица.


Задаваме всички стойности, както е на фигурата:

Пътят до аватара ще бъде записан в това поле и ще бъде записан в отделна папка, нека я наречем "аватари". Папката ще се намира в същата директория като останалите файлове на скрипта.

3.Отидете до файла спаси_ потребител. phpи добавете следния код, след като премахнете интервалите от данните за вход и паролата:

// премахване на допълнителни интервали
$login = подрязване($login);

// добави нов ********************************************** ***

// добавете проверка за дължината на данните за вход и парола
ако (strlen($login)< 3 or strlen($login) > 15) {
изход („Входът трябва да съдържа поне 3 знака и не повече от 15.“);
}
if (strlen($password)< 3 or strlen($password) > 15) {
exit("Паролата трябва да е най-малко 3 знака и най-много 15.");
}

if (!empty($_POST["fupload"])) //Проверете дали потребителят е изпратил изображение
{
$fupload=$_POST["fupload"]; $fupload = трим($fupload);
ако ($fupload =="" или празно($fupload)) (
unset($fupload);// ако променливата $fupload е празна, изтрийте я
}
}
ако (!isset($fupload) или празен ($fupload) или $fupload =="")
{
//ако променливата не съществува (потребителят не е изпратил изображение), тогава му присвояваме предварително подготвено изображение с надпис "без аватар"
$avatar = "avatars/net-avatara.jpg"; //можете да нарисувате net-avatara.jpg или да го вземете от източника
}
друго
{
//в противен случай - зарежда изображението на потребителя
$path_to_90_directory = "avatars/";//папка, където ще се зареди първоначалното изображение и неговото компресирано копие

If(preg_match("/[.](JPG)|(jpg)|(gif)|(GIF)|(png)|(PNG)$/",$_FILES["fupload"]["име"])) //проверете оригиналния формат на изображението
{
$filename = $_FILES["fupload"]["name"];
$source = $_FILES["fupload"]["tmp_name"];
$target = $path_to_90_directory. $ име на файл;
move_uploaded_file($source, $target);//качете оригинала в $path_to_90_directory
if(preg_match("/[.](GIF)|(gif)$/", $filename)) (
$im = imagecreatefromgif($path_to_90_directory.$filename) ; //ако оригиналът е бил във формат gif, тогава създаваме изображение в същия формат. Изисква се за последващо компресиране
}
if(preg_match("/[.](PNG)|(png)$/", $filename)) (
$im = imagecreatefrompng($path_to_90_directory.$filename) ;//ако оригиналът е във формат png, създайте изображение в същия формат. Изисква се за последващо компресиране
}

If(preg_match("/[.](JPG)|(jpg)|(jpeg)|(JPEG)$/", $filename)) (
$im = imagecreatefromjpeg($path_to_90_directory.$filename); //ако оригиналът е във формат jpg, създайте изображение в същия формат. Изисква се за последващо компресиране
}
//СЪЗДАВАНЕТО НА КВАДРАТНО ИЗОБРАЖЕНИЕ И ПОСЛЕДВАЩОТО МУ КОМПРЕСИРАНЕ Е ВЗЕТО ОТ САЙТА www.codenet.ru
// Създаване на квадрат 90x90
// dest - получено изображение
// w - ширина на изображението
// ratio - коефициент на пропорционалност
$w = 90; // квадрат 90х90. Можете да доставите и други размери.
// създаване на изходно изображение въз основа на
// изходен файл и определете размера му
$w_src = imagesx($im); //изчислете ширината
$h_src = imagesy($im); //изчислете височината на изображението
// създаване на празно квадратно изображение
// truecolor е важен!, в противен случай ще имаме 8-битов резултат
$dest = imagecreatetruecolor($w,$w);
// изрежете центъра на квадрата с x, ако снимката е хоризонтална
ако ($w_src>$h_src)
imagecopyresampled($dest, $im, 0, 0,
кръг ((макс. ($w_src,$h_src)-мин($w_src,$h_src))/2),
0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
// изрежете квадратния връх в y,
// ако снимката е вертикална (въпреки че можете да имате и средата)
ако ($w_src<$h_src)
imagecopyresampled($dest, $im, 0, 0, 0, 0, $w, $w,
min($w_src,$h_src), min($w_src,$h_src));
// квадратното изображение е мащабирано без изрязвания
ако ($w_src==$h_src)
imagecopyresampled($dest, $im, 0, 0, 0, 0, $w, $w, $w_src, $w_src);
$date=time(); //изчисляване на времето в настоящия момент.
imagejpeg($dest, $path_to_90_directory.$date.".jpg");//запазете jpg изображението в желаната папка, името ще бъде текущият час. Уверете се, че аватарите нямат едно и също име.
// защо jpg? Заема много малко място + унищожава анимирания gif на изображението, който разсейва потребителя. Не е много приятно да четеш коментара му, когато забележиш някакво движение с крайчеца на окото си.
$avatar = $path_to_90_directory.$date.".jpg";//поставете пътя до аватара в променливата.
$delfull = $path_to_90_directory.$filename;
unlink ($delfull);//премахнете оригиналното качено изображение, вече не ни трябва. Задачата беше да се получи миниатюра.
}
друго
{
//в случай на несъответствие на формата, издайте съответното съобщение
exit("Аватарът трябва да е във формат JPG, GIF или PNG");
}
//край на процеса на зареждане и присвояване на адреса на заредената ava към променливата $avatar
}



// добави нов ************************************************* ****
// Следва всичко от първата част на статията, но е необходимо да добавите промяната към заявката към базата данни.
//свържете се с базата данни
// проверка за съществуването на потребител със същото логин
$result = mysql_query("SELECT id FROM потребители WHERE login="$login"",$db);
if (!empty($myrow["id"])) (
exit("Съжаляваме, въведеното потребителско име вече е регистрирано. Моля, въведете друго потребителско име.");
}
// ако няма такъв, запазете данните
$result2 = mysql_query ("INSERT INTO потребители (вход,парола,аватар) VALUES("$login","$password","$avatar")");
// Проверете дали има грешки
ако ($result2=="TRUE")
{
echo "Регистрирахте се успешно! Вече можете да влезете в сайта. Главна страница";
}
иначе(
echo "Грешка! Не сте влезли в системата.";
}
?>

4. Трябва да добавите една таблица към същата база данни. Той ще съхранява ip-адреси, които са направили грешки при влизане. Така можем да ограничим достъпа до онези, които са сгрешили повече от три пъти подред за около 15 мин. Мисля, че програмите, които отгатват пароли, ще трябва да се бъркат дълго време.
Нека да отидем на phpmyadmin и да създадем нова таблица с 3 полета:


ip - ip адрес.
date - дата на неуспешно влизане за последните 15 минути за потребителя с даденото ip. col - броят грешки през последните 15 минути за потребителя с даденото ip.
Страхотен! Готово, сега нека променим файла за проверка на данните за вход и парола, защото сега паролата ни е криптирана. Отворете testreg.php и изтрийте всичко освен премахването на интервали от потребителско име и парола. След това добавете следния код:

// премахване на допълнителни интервали
$login = подрязване($login);
$парола = трим($парола);

// замяна с нов ********************************************* ***
// свързване към базата данни
include("bd.php");// файлът bd.php трябва да е в същата папка като всички останали, ако не е, просто променете пътя
// минипроверка за отгатване на пароли
$ip=getenv("HTTP_X_FORWARDED_FOR");
if (празен($ip) || $ip=="неизвестен") ( $ip=getenv("REMOTE_ADDR"); )//извличане на ip
mysql_query ("DELETE FROM error WHERE UNIX_TIMESTAMP() - UNIX_TIMESTAMP(date) > 900");//изтриване на ip адреси на потребители, които са направили грешка при влизане след 15 минути.
$result = mysql_query("SELECT col FROM oshibka WHERE ip="$ip"",$db);// извлича от базата данни броя на неуспешните опити за влизане през последните 15 за потребител с дадения ip
$myrow = mysql_fetch_array($result);
if ($myrow["col"] > 2) (
//ако има повече от две грешки, т.е. три, тогава издаваме съобщение.
exit("Въведохте вашето потребителско име или парола неправилно 3 пъти. Моля, изчакайте 15 минути, преди да опитате отново.");
}
$password = md5($password);//шифроване на парола
$password = strrev($password);// за надеждност добавете реверс
$парола = $парола."b3p6f";
//можете да добавите някои от героите си по вкус, например като въведете "b3p6f". Ако тази парола бъде хакната чрез груба сила на сървъра на същия md5, тогава очевидно нищо добро няма да излезе от това. Но ви съветвам да поставите други знаци, можете в началото на реда или в средата.
//В този случай е необходимо да се увеличи дължината на полето за парола в базата данни. Шифрованата парола може да бъде много по-голяма.

$result = mysql_query("SELECT * FROM users WHERE login="$login" И парола="$password"",$db); //извличане на всички данни за потребителя с въведените потребителско име и парола от базата данни
$myrow = mysql_fetch_array($result);
ако (празно ($myrow["id"]))
{
//ако потребителят с въведеното име и парола не съществува
//Направете запис, че даденият ip не може да влезе.
$select = mysql_query("SELECT ip FROM грешка WHERE ip="$ip"");
$tmp = mysql_fetch_row($select);
if ($ip == $tmp) (// проверка дали има потребител в таблицата "oshibka"
$result52 = mysql_query("SELECT col FROM грешка WHERE ip="$ip"",$db);
$myrow52 = mysql_fetch_array($result52);
$col = $myrow52 + 1;// добавяне на нов неуспешен опит за влизане
mysql_query("Грешка при актуализация SET col=$col,date=NOW() WHERE ip="$ip"");
}
иначе(
mysql_query ("INSERT INTO грешка (ip,date,col) VALUES ("$ip",NOW(),"1")");
//ако не е имало грешки през последните 15 минути, тогава вмъкнете нов запис в таблицата "oshibka"
}

exit("Съжаляваме, потребителското име или паролата, които сте въвели, са неправилни.");
}
иначе(
nbsp; //ако паролите съвпадат, тогава започваме сесията за потребителя! Можете да го поздравите, той влезе!
$_SESSION["password"]=$myrow["password"];
$_SESSION["login"]=$myrow["login"];
$_SESSION["id"]=$myrow["id"];//тези данни се използват много често, така че влезлият потребител ще ги "носи"

//След това съхраняваме данните в бисквитки за по-късно влизане.
//ВНИМАНИЕ!!! НАПРАВЕТЕ ТОВА ПО ВАШЕ УМОЛЧЕНИЕ, ТЪЙ КАТО ДАННИТЕ СЕ СЪХРАНЯВАТ В БИСКВИТКИ БЕЗ КРИПТИРАНЕ
if ($_POST["save"] == 1) (
//Ако потребителят иска данните му да бъдат запазени за по-късно влизане, ние ги запазваме в бисквитките на неговия браузър
setcookie("влизане", $_POST["влизане"], време()+9999999);
setcookie("парола", $_POST["парола"], време()+9999999);
}}
ехо " ";//пренасочва потребителя към главната страница, където ще бъде информиран за успешно влизане
?>

5. Променете изцяло главната страница. Необходимо е върху него да се покаже аватар на потребителя, да се покаже връзка за излизане от акаунта и да се добави квадратче за запомняне на паролата при влизане.
Index.php

// цялата процедура работи на сесии. Именно в него се съхраняват данните на потребителя, докато той е на сайта. Много е важно да ги стартирате в самото начало на страницата!!!
session_start();
include("bd.php");// файлът bd.php трябва да е в същата папка като всички останали, ако не е, просто променете пътя
if (!empty($_SESSION["login"]) и !empty($_SESSION["password"]))
{
//ако в сесиите има потребителско име и парола, проверете ги и извлечете аватара
$login = $_SESSION["влизане"];
$password = $_SESSION["парола"];
$result = mysql_query("SELECT id,avatar FROM users WHERE login="$login" И парола="$password"",$db);
$myrow = mysql_fetch_array($result);
//извличане на необходимите потребителски данни
}
?>


Главна страница


Главна страница

if (!isset($myrow["avatar"]) или $myrow["avatar"]=="") (
//проверете дали данните на потребителя са извлечени от базата данни. Ако не, значи не е влязъл или паролата в сесията е неправилна. Показване на прозореца за влизане. Но няма да го показваме на тези, които са влезли, те вече не се нуждаят от него.
печат<<


ТУК;

If (isset($_COOKIE["login"])) //има ли променлива с логин в COOKIE. Трябва да бъде, ако потребителят е щракнал върху квадратчето „Запомни ме“ по време на предишното влизане
{
//ако да, тогава вмъкнете стойността му във формуляра. В този случай на потребителя се показва, че неговото име за вход вече е въведено в необходимата колона
echo "value="".$_COOKIE["login"]."">";
}

печат<<




ТУК;

If (isset($_COOKIE["password"]))//има ли променлива за парола в COOKIE. Трябва да бъде, ако потребителят е щракнал върху квадратчето „Запомни ме“ по време на предишното влизане
{
//ако да, тогава вмъкнете стойността му във формуляра. В този случай на потребителя се показва, че паролата му вече е въведена в необходимата колона.
echo "value="".$_COOKIE["password"]."">";
}

печат<<



Помни ме.






Регистрирам



Вие сте влезли като гост

ТУК;
}
друго
{
// при успешно влизане, потребителят получава всичко, което се намира по-долу между звездичките.

печат<<
Вие сте влезли като $_SESSION (изход)


Тази връзка е достъпна само за регистрирани потребители

Вашият аватар:




ТУК;

//************************************************************************************
//при успешно влизане, потребителят получава всичко, което се намира ГОРЕ между звездичките.
}
?>

6. Необходимо е да се даде възможност на потребителите, които са влезли в системата, да излизат. На главната страница вече имаше връзка за изход. Но този файл все още не съществува. Така че нека създадем нов файл изход.phpс код:

session_start();
ако (празно($_SESSION["вход"]) или празно($_SESSION["парола"]))
{
//ако няма сесия с потребителско име и парола, този файл е достъпен от невлязъл потребител. Не му е мястото тук. Издайте съобщение за грешка, спрете скрипта
изход („Достъпът до тази страница е разрешен само за регистрирани потребители. Ако сте регистрирани, влезте в сайта, като използвате вашето потребителско име и парола
Главна страница");
}

unset($_SESSION["парола"]);
unset($_SESSION["вход"]);
unset($_SESSION["id"]);// унищожаване на променливи в сесии
изход(" ");
// изпращане на потребителя на главната страница.
?>

Добре, всичко свърши! Използвайте със здраве! Късмет!