Zəif istifadəçi məlumatı php. Superqlobal massiv $_SERVER

İnformasiyanın səmərəli təşkili, axtarışı və yayılması imkanları kompüter texnologiyaları sahəsində mütəxəssisləri çoxdan maraqlandırır. İnformasiya əsasən hərf-rəqəm simvollarından ibarət mətn olduğundan mətni təsvir edən qanunauyğunluqlar üzrə informasiyanın axtarışı və emalı vasitələrinin işlənib hazırlanması ciddi nəzəri tədqiqat obyektinə çevrilmişdir.

Nümunə axtarışı yalnız konkret mətn fraqmentlərini tapmağa deyil, həm də onları başqa fraqmentlərlə əvəz etməyə imkan verir. Nümunə uyğunluğun standart nümunələrindən biri mətn redaktorlarında tap/dəyişdirmə əmrləridir – məsələn, MS Word, Emacs və mənim sevimli redaktorum, vi. Bütün UNIX istifadəçiləri sed, awk və grep kimi proqramlarla tanışdırlar; Bu proqramların imkanlarının zənginliyi əsasən onların nümunə axtarış imkanları ilə bağlıdır. Nümunə axtarış mexanizmləri dörd əsas problemi həll edir:

  • verilmiş nümunəyə tam uyğun gələn sətirləri axtarın;
  • verilmiş nümunəyə uyğun gələn sətir fraqmentlərinin axtarışı;
  • naxışdan istifadə edərək sətirlərin və alt sətirlərin dəyişdirilməsi;
  • verilmiş nümunə ilə sətirləri axtarın uyğun gəlmir.

İnternetin yaranması bütün dünyada istifadəçilərə milyardlarla veb səhifədə lazım olan məlumatları tapmağa imkan verən daha sürətli və daha səmərəli məlumat axtarış vasitələrinə ehtiyac yaratdı. Axtarış motorları, onlayn maliyyə xidmətləri və e-ticarət saytları bu sektorlardakı böyük həcmli məlumatların təhlili üçün vasitələr olmadan tamamilə faydasız olardı. Həqiqətən də, sətirli informasiyanın emalı vasitələri müasir informasiya texnologiyaları ilə bu və ya digər şəkildə bağlı olan demək olar ki, istənilən sektorun mühüm tərkib hissəsidir. Bu fəsildə PHP-də sətirlərin işlənməsi vasitələrinə diqqət yetirilir. Biz bəzi standart sətir funksiyalarına baxacağıq (onlardan dildə 60-dan çoxu var!) və verilən təriflər və nümunələr sizə veb proqramlar yaratmaq üçün lazım olan məlumatları verəcəkdir. Ancaq PHP-nin xüsusiyyətlərinə keçməzdən əvvəl sizi nümunə axtarışını mümkün edən əsas mexanizmlə tanış etmək istəyirəm. Söhbət müntəzəm ifadələrdən gedir.

Adi ifadələr

Normal ifadələr bütün müasir naxış uyğunlaşdırma texnologiyalarının əsasını təşkil edir. Normal ifadə axtarılan mətni təsvir edən sadə və xidmət simvollarının ardıcıllığıdır. Bəzən müntəzəm ifadələr sadə və aydın olur (məsələn, it sözü), lakin çox vaxt onlar müntəzəm ifadə sintaksisində xüsusi məna kəsb edən xüsusi simvolları ehtiva edir - məsələn,<(?)>.*<\/.?>.

PHP-də iki funksiya ailəsi var ki, onların hər biri müxtəlif tipli müntəzəm ifadələrdir: POSIX üslubu və ya Perl üslubu. Hər bir nizamlı ifadə növünün öz sintaksisi var və fəslin müvafiq hissəsində müzakirə olunur. Bu mövzuda çoxlu dərsliklər yazılmışdır və onları həm İnternetdə, həm də kitab mağazalarında tapmaq olar. Buna görə də, mən hər növ haqqında yalnız əsas məlumatları təqdim edəcəyəm və istəsəniz, əlavə məlumatı özünüz tapa bilərsiniz. Əgər müntəzəm ifadələrin necə işlədiyi ilə hələ tanış deyilsinizsə, bu bölmənin qalan hissəsini əhatə edən qısa giriş təlimatını oxumağınızdan əmin olun. Və bu sahədə yaxşı məlumatınız varsa, növbəti hissəyə keçməkdən çəkinməyin.

Normal ifadə sintaksisi (POSIX)

POSIX müntəzəm ifadələrinin strukturu bir qədər tipik riyazi ifadələrin strukturunu xatırladır - müxtəlif elementlər (operatorlar) bir-biri ilə birləşərək daha mürəkkəb ifadələr əmələ gətirirlər. Bununla belə, nizamlı ifadələri belə güclü və ifadəli alət edən elementlərin birləşdirilməsi hissidir. İmkanlar hərfi mətnin axtarışı ilə məhdudlaşmır (məsələn, konkret söz və ya rəqəm); müxtəlif semantikalı, lakin oxşar sintaksisi olan sətirləri axtara bilərsiniz - məsələn, fayldakı bütün HTML teqləri.

Ən sadə müntəzəm ifadə tək hərfi xarakterə uyğun gəlir - məsələn, g ifadəsi g kimi sətirlərə uyğun gəlir , bazarlıq və çanta. Çoxsaylı hərfi simvolların birləşməsindən yaranan ifadə eyni qaydalara uyğun gəlir - məsələn, gan ardıcıllığı həmin simvolları ehtiva edən hər hansı sətirdə uyğun gəlir (məsələn, dəstə, təşkilat və ya Reyqan).

Operator | (şaquli bar) bir neçə alternativdən birinin uyğun olub olmadığını yoxlayır. Məsələn, müntəzəm ifadə php | zend sətri php və ya zend üçün yoxlayır.

Kvadrat mötərizələr

Kvadrat mötərizələr () müntəzəm ifadələr kontekstində xüsusi məna daşıyır -- onlar "mötərizədə göstərilən hər hansı simvol" deməkdir. php hərfi mətni olan bütün sətirlərə uyğun gələn php normal ifadəsindən fərqli olaraq, ifadə p və ya h simvollarını ehtiva edən istənilən sətirdə uyğun gəlir. Daimi ifadələrlə işləyərkən kvadrat mötərizələr mühüm rol oynayır, çünki axtarış prosesi çox vaxt verilmiş intervaldan simvol tapmaq vəzifəsini əhatə edir. Aşağıda bəzi tez-tez istifadə olunan intervallar verilmişdir:

  • -- 0-dan 9-a kimi istənilən onluq rəqəmə uyğun gəlir;
  • -- a-dan z-ə qədər istənilən kiçik hərflə uyğun gəlir;
  • -- A-dan Z-ə qədər istənilən böyük hərflə uyğun gəlir;
  • -- a-dan z-ə qədər hər hansı kiçik və ya böyük hərflə uyğun gəlir.

Əlbəttə ki, yuxarıda sadalanan intervallar sadəcə ümumi prinsipi nümayiş etdirir. Məsələn, siz 0-dan 3-ə qədər hər hansı onluq rəqəmi göstərmək üçün boşluqdan və ya b-dən v-ə qədər hər hansı kiçik hərf simvolunu göstərmək üçün boşluqdan istifadə edə bilərsiniz. Bir sözlə, intervallar tamamilə özbaşına müəyyən edilir.

Kəmiyyət göstəriciləri

Kvadrat mötərizədə bir simvolun və ya quruluşun təkrarlarının sayını göstərən xüsusi xidmət simvolları sinfi var. Bu xüsusi simvollar (+, * və (...)) adlanır kəmiyyət göstəriciləri. Onların iş prinsipini misallarla izah etmək ən asandır:

  • p+ ardıcıl bir və ya bir neçə p simvolu deməkdir;
  • p* ardıcıl olaraq sıfır və ya daha çox p simvolu deməkdir;
  • R? sıfır və ya bir simvol p deməkdir;
  • p(2) ardıcıl iki p simvol deməkdir;
  • p(2,3) ard-arda iki-üç p simvolu deməkdir;
  • p(2,) ard-arda iki və ya daha çox p simvolu deməkdir.

Digər xidmət simvolları

$ və ^ xidmət simvolları simvollara uyğun gəlmir, lakin sətirdəki xüsusi mövqelərə uyğun gəlir. Məsələn, p$ ifadəsi p simvolu ilə bitən sətir, ^p ifadəsi isə p simvolu ilə başlayan sətir deməkdir.

  • [^a-zA-Z] konstruksiyası istənilən xarakterə uyğun gəlir daxil deyil göstərilən intervallarda (a-z və A-Z).
  • Xidmət simvolu. (nöqtə) "hər hansı bir simvol" deməkdir. Məsələn, p.p ifadəsi p simvoluna uyğun gəlir, ardınca ixtiyari simvol, ardınca yenə p simvolu gəlir.

Xidmət simvollarının birləşməsi daha mürəkkəb ifadələrlə nəticələnir. Bir neçə nümunəyə baxaq:

  • ^.(2)$ -- ehtiva edən hər hansı sətir hamar iki simvol;
  • (.*)-- arasında ixtiyari simvol ardıcıllığı<Ь>Və(ehtimal ki, qalın mətni göstərmək üçün HTML teqləri);
  • p(hp)* -- p simvolundan sonra hp ardıcıllığının sıfır və ya daha çox nümunəsi (məsələn, phphphp).

Bəzən təsvir olunan xüsusi kontekstdə istifadə etmək əvəzinə sətirlərdə xüsusi simvollar tapmaq lazımdır. Bunu etmək üçün, xidmət simvolları əks kəsik (\) ilə qaçır. Məsələn, bir dollar məbləğində pul axtarmaq üçün \$+ ifadəsini istifadə edə bilərsiniz, yəni "bir və ya daha çox onluq rəqəmdən sonra dollar işarəsi". $-dan əvvəl əks kəsik işarəsinə diqqət yetirin. Bu normal ifadə üçün mümkün uyğunluqlar $42, $560 və $3-dür.

Standart interval ifadələri (simvol sinifləri)

Proqramlaşdırmanın asanlığı üçün POSIX standartı da adlandırılan bəzi standart interval ifadələrini müəyyən etmişdir xarakter sinifləri(xarakter sinifləri). Simvol sinfi verilmiş diapazondan bir simvol təyin edir -- məsələn, əlifbanın hərfi və ya rəqəm:

  • [[:alpha:]] -- əlifba simvolu (aA-zZ);
  • [[:rəqəmli:]]-rəqəmli (0-9);
  • [[:alnum:]] -- əlifba simvolu (aA-zZ) və ya rəqəm (0-9);
  • [[:space:]] -- boşluq (yeni sətirlər, nişanlar və s.).

Normal ifadələrlə işləmək üçün PHP funksiyaları (POSIX uyğun)

PHP hazırda POSIX tipli normal ifadələrdən istifadə edərək yeddi axtarış funksiyasını dəstəkləyir:

  • ereg();
  • ereg_replace();
  • eregi();
  • eregi_replace();
  • bölün ();
  • bölün ();
  • sql_regcase().

Bu funksiyaların təsviri aşağıdakı bölmələrdə verilmişdir.

ereg() funksiyası verilmiş sətirdə nümunə üçün uyğunluq axtarır. Uyğunluq aşkar edilərsə, TRUE qaytarılır, əks halda FALSE qaytarılır. ereg() funksiyasının sintaksisi:

int ereg (sətir nümunəsi, sətir sətri [, massiv uyğun gəlir])

Axtarış əlifba simvollarının halı nəzərə alınmaqla aparılır. Domains.com sətirlərində axtarış etmək üçün ereg() funksiyasından istifadə nümunəsi:

$is_com - ereg("(\.)(com$)", $email):

// $email ".com" simvolları ilə bitərsə, funksiya TRUE qaytarır

// Xüsusilə, sətirlər üçün axtarış uğurlu olacaq

// "www.wjgilmore.com" və " [email protected]"

Qeyd edək ki, $ simvolunun mövcudluğuna görə nizamlı ifadə yalnız sətir .com simvolları ilə bitərsə uyğun gəlir. Məsələn, "www.apress.com" sətrinə uyğun olacaq, lakin uyğun gəlməyəcək"www.apress.com/catalog" sətirində.

Əlavə uyğunluq parametri normal ifadədə mötərizə içərisində olan bütün alt ifadələr üçün uyğunluqlar massivindən ibarətdir. Siyahı 8.1 URL-i bir neçə seqmentə bölmək üçün bu massivdən necə istifadə olunacağını göstərir.

Siyahı 8.1. $regs massivinin çap elementləri

$url = "http://www.apress.com";

// $url-i üç komponentə bölün: "http://www". "apress" və "com"

$www_url = ereg("^(http://www)\.([[:alnum:]+\.([[:alnum:]]+)". $url, $regs);

əgər ($www_url) : // Əgər $www_url URL-dən ibarətdirsə

echo $regs; // Bütün sətir "http://www.apress.com"

çap "
";

echo $regs[l]; // "http://www"

çap "
";

echo $regs; // "apress"

çap "
";

echo $regs; // "com" endif;

Skripti Siyahı 8.1-də işlətmək aşağıdakı nəticəni verir:

http://www.apress.com http://www.apress com

ereg_replace() funksiyası verilmiş sətirdə nümunə üçün uyğunluq axtarır və onu yeni fraqmentlə əvəz edir. ereg_replace() funksiyasının sintaksisi:

string ereg_replace (simli naxış, simin dəyişdirilməsi, simli sim)

ereg_replace() funksiyası ereg() funksiyası ilə eyni prinsiplə işləyir, lakin onun imkanları sadə axtarışdan əvəzetmə ilə axtarışa qədər genişləndirilir. Əvəzetməni yerinə yetirdikdən sonra funksiya dəyişdirilmiş sətri qaytarır. Əgər uyğun gəlirsə

yoxdur, xətt eyni vəziyyətdə qalır. ereg_replace() funksiyası, ereg() kimi hərflərə həssasdır. Aşağıda bu funksiyanın istifadəsini göstərən sadə bir nümunə verilmişdir:

$copy_date = "Müəllif hüququ 1999":

$copy_date = ereg_replace("(+)". "2000", $copy_date);

print $copy_date: // "Müəllif hüququ 2000" sətirini çap edir

PHP-nin axtarış və dəyişdirmə alətlərinin maraqlı xüsusiyyətlərindən biri əsas ifadənin mötərizədə verilmiş hissələrinə arxa istinadlardan istifadə etmək imkanıdır. Arxa istinadlar ereg() funksiyasının əlavə uyğunluq parametrinin elementlərinə bənzəyir, bir istisna ilə: arxa istinadlar \0, \1, \2 və s. kimi yazılır, burada \0 bütün sətirlə, \1 uğurlu uyğunluqla uyğun gəlir. ilk alt ifadə və s. İfadə 9-a qədər geri keçid ola bilər. Aşağıdakı nümunə mətndəki bütün URL bağlantılarını işləyən hiperlinklərlə əvəz edir:

$url = "Apress (http://www.apress.com");

$url = ereg_replace("http://(()*)", " \\0", $url);

// Xətt göstərilir:

// Apress (http://www.apress.com)

eregi() funksiyası verilmiş sətirdə nümunə üçün uyğunluğu axtarır. eregi() funksiyasının sintaksisi:

int eregi (sətir nümunəsi, sətir sətri [, massiv uyğun gəlir])

Axtarış davam edir istisna olmaqlaəlifba simvollarının vəziyyəti. eregi() funksiyası xüsusilə daxil edilmiş sətirlərin (məsələn, parollar) etibarlılığını yoxlamaq üçün faydalıdır. eregi() funksiyasının istifadəsi aşağıdakı nümunədə nümayiş etdirilir:

$parol = "abc";

if (! eregi("[[:alnum:]](8.10), $parol) :

print "Yanlış parol! Parollar 8-10 simvol uzunluğunda olmalıdır.";

// Bu fraqmentin icrası nəticəsində xəta mesajı göstərilir.

// çünki "abc" sətirinin uzunluğu icazə verilən interval daxilində deyil

// 8-dən 10 simvola qədər.

Eregi_replace() funksiyası tam olaraq ereg_replace() funksiyası ilə eyni işləyir, bir istisna ilə: axtarış hərf hərfinə həssasdır. ereg_replace() funksiyasının sintaksisi:

string eregi_replace (sətir şablonu, simin dəyişdirilməsi, simli sətir)

Split() funksiyası sətri verilmiş nümunə ilə müəyyən edilmiş sərhədləri olan elementlərə bölür. Split() funksiyasının sintaksisi:

massiv bölünməsi (sətir nümunəsi, sətir sətri [, int həddi])

İsteğe bağlı eşik parametri sətirin soldan sağa bölündüyü elementlərin maksimum sayını təyin edir. Nümunədə əlifba simvolları varsa, spl it() funksiyası hərflərə həssasdır. Aşağıdakı nümunə kanonik IP ünvanını üçlüyə bölmək üçün split() funksiyasının istifadəsini nümayiş etdirir:

$ip = "123.345.789.000"; // Kanonik IP ünvanı

$iparr = bölün ("\.", $ip) // Çünki nöqtə xidmət simvoludur.

// qaçmaq lazımdır.

çap "$iparr
"; // Çıxışlar "123"

çap "$iparr
"; // Çıxışlar "456"

çap "$iparr
"; // Çıxışlar "789"

çap "$iparr
"; // Çıxışlar "000"

Spliti() funksiyası bir istisna olmaqla, split() prototipi kimi işləyir: it nəzərə almır simvol reyestri. Spliti() funksiyasının sintaksisi:

massiv bölünməsi (sətir nümunəsi, sətir sətri [, int həddi])

Təbii ki, halda yalnız naxışda əlifba simvolları olduqda vacibdir. Digər simvollar üçün spliti() funksiyası split() ilə tam olaraq eynidir.

sql_regcase() köməkçi funksiyası giriş sətirindəki hər simvolu kvadrat mötərizələrə yığır və uyğun simvolu əlavə edir. sql_regcase() funksiyasının sintaksisi:

sətir sql_regcase (sətir sətri)

Əgər əlifba simvolu iki variantda (böyük və kiçik hərf) mövcuddursa, kvadrat mötərizədəki ifadə hər iki variantı ehtiva edir; əks halda orijinal simvol iki dəfə təkrarlanır. sql_regcase() funksiyası PHP-dən tək hərfli müntəzəm ifadələri dəstəkləyən proqram paketləri ilə istifadə edərkən xüsusilə faydalıdır. sql_regcase() funksiyasından istifadə edərək sətri çevirmək nümunəsi:

$versiya = "php 4.0";

çap sql_regcase($versiya);

// Sətiri göstərir [..]

Perl üslublu müntəzəm ifadə sintaksisi

Sətirin böyük və kiçik hərflərə çevrilməsi

PHP-də sətirlərin hərfini dəyişdirmək üçün nəzərdə tutulmuş dörd funksiya var:

  • strtolower();
  • strtoupper();
  • ucfirst();
  • ucwords().

Bütün bu xüsusiyyətlər aşağıda ətraflı təsvir edilmişdir.

strtolower()

strtolower() funksiyası sətirdəki bütün əlifba simvollarını kiçik hərflərə çevirir. strtolower() funksiyasının sintaksisi:

string strtolower(string string)

Qeyri-əlifba simvolları funksiya tərəfindən dəyişdirilmir. strtolower() funksiyasından istifadə edərək sətri kiçik hərflərə çevirmək aşağıdakı nümunədə nümayiş etdirilir:

$sentence = strtolower($sentence);

// "Pişirmə və proqramlaşdırma php mənim iki sevimli məşğuliyyətimdir!"

Sətirlər yalnız kiçik hərflərə deyil, həm də böyük hərfə çevrilə bilər. Dönüşüm aşağıdakı sintaksisə malik olan strtoupper() funksiyası tərəfindən həyata keçirilir:

string strtoupper (string string)

Qeyri-əlifba simvolları funksiya tərəfindən dəyişdirilmir. strtoupper() funksiyasından istifadə edərək sətri böyük hərflərə çevirmək aşağıdakı nümunədə nümayiş etdirilir:

$sentence = "PHP bişirmək və proqramlaşdırmaq mənim iki sevimli məşğuliyyətimdir!";

$sentence = strtoupper($sentence);

// Funksiyaya zəng etdikdən sonra $sentence sətri ehtiva edir

// "PHP BİTMİŞLƏRİ VƏ PROQRAMLAŞDIRMA MƏNİM İKİ SEVDİYİM ƏMƏNƏMDİR!"

ucfirst() funksiyası əlifba simvolu olması şərti ilə sətirin ilk simvolunu böyük hərfə çevirir. ucfirst() funksiyasının sintaksisi:

ucfirst string (simli sətir)

Qeyri-əlifba simvolları funksiya tərəfindən dəyişdirilmir. Sətirin birinci simvolunun ucfirst() funksiyası ilə çevrilməsi aşağıdakı nümunədə nümayiş etdirilir:

&sentence = "Pişirmə və proqramlaşdırma PHP mənim iki sevimli məşğuliyyətimdir!";

$sentence = ucfirst($sentence);

// Funksiyaya zəng etdikdən sonra $sentence sətri ehtiva edir

// "Pişirmə və proqramlaşdırma PHP mənim iki sevimli məşğuliyyətimdir!"

ucwords() funksiyası sətirdəki hər sözün ilk hərfini böyük hərflərə çevirir. ucwords() funksiyasının sintaksisi:

string ucwords (string string")

Qeyri-əlifba simvolları funksiya tərəfindən dəyişdirilmir. "Söz" sətirin digər elementlərindən boşluqlarla ayrılmış simvollar ardıcıllığı kimi müəyyən edilir. Aşağıdakı nümunə ucwords() funksiyasının sözlərin ilk simvollarını necə çevirdiyini nümayiş etdirir:

$sentence = "PHP bişirmək və proqramlaşdırmaq mənim iki sevimli məşğuliyyətimdir!";

$sentence = ucwords($sentence);

// Funksiyaya zəng etdikdən sonra $sentence sətri ehtiva edir

// "Pişirmə və proqramlaşdırma PHP mənim iki sevimli məşğuliyyətimdir!"

Layihə: Brauzerin İdentifikasiyası

İstifadəçilər üçün əlverişli veb-sayt yaratmağa çalışan hər bir proqramçı sayta müxtəlif brauzerlərdə və əməliyyat sistemlərində baxarkən səhifə formatındakı fərqləri nəzərə almalıdır. Baxmayaraq ki, W3 konsorsiumu (http://www.w3.org) proqramçıların veb proqramlar yaratarkən riayət etməli olduğu standartları dərc etməyə davam edir, brauzer tərtibatçıları bu standartlara öz kiçik “təkmilləşdirmələrini” əlavə etməyi xoşlayırlar ki, bu da son nəticədə xaosa və çaşqınlığa səbəb olur. . Tərtibatçılar tez-tez bu problemi hər növ brauzer və əməliyyat sistemi üçün müxtəlif səhifələr yaratmaqla həll edirlər - bu, iş yükünü əhəmiyyətli dərəcədə artırır, lakin nəticədə sayt hər bir istifadəçi üçün idealdır. Nəticə sayt üçün yaxşı reputasiya və istifadəçinin onu yenidən ziyarət edəcəyinə inamdır.

İstifadəçiyə öz brauzeri və əməliyyat sisteminə uyğun formatda səhifəyə baxmaq imkanı vermək üçün brauzer və platforma haqqında məlumat daxil olan səhifə sorğusundan çıxarılır. Lazımi məlumatları aldıqdan sonra istifadəçi istədiyi səhifəyə yönləndirilir.

Aşağıdakı layihə (sniffer.php) sorğulardan məlumat almaq üçün müntəzəm ifadələrlə işləmək üçün PHP funksiyalarından necə istifadə olunacağını göstərir. Proqram brauzerin və əməliyyat sisteminin növünü və versiyasını müəyyən edir və sonra alınan məlumatları brauzer pəncərəsində göstərir. Amma proqramın faktiki təhlilinə keçməzdən əvvəl onun əsas komponentlərindən birini - standart PHP dəyişənini $HTTP_USER_AGENT ilə tanış etmək istəyirəm. Bu dəyişən istifadəçinin brauzeri və əməliyyat sistemi haqqında müxtəlif məlumatları sətir formatında saxlayır - məhz bizi maraqlandıran. Bu məlumat yalnız bir əmrlə ekranda asanlıqla göstərilə bilər:

echo $HTTP USER_AGENT;

Windows 98 kompüterində Internet Explorer 5.0 işlədərkən nəticə belə görünəcək:

Mozilla/4.0 (uyğundur; MSIE 5.0; Windows 98; DigExt)

Netscape Navigator 4.75 üçün aşağıdakı məlumatlar göstərilir:

Mozilla/4.75 (Win98; U)

Sniffer.php $HTTP_USER_AGENT-dən sətir emalı və müntəzəm ifadə funksiyalarından istifadə edərək lazımi məlumatları çıxarır. Pseudocode proqram alqoritmi:

  • Brauzer və əməliyyat sistemini müəyyən etmək üçün iki funksiya təyin edin: browser_info() və opsys_info(). Brauzer_info() funksiyasının psevdokodu ilə başlayaq.
  • Eged() funksiyasından istifadə edərək brauzer növünü təyin edin. Bu funksiya strstr( kimi sadələşdirilmiş sətir funksiyalarından yavaş olsa da, bu halda daha rahatdır, çünki müntəzəm ifadə brauzerin versiyasını təyin etməyə imkan verir.
  • Aşağıdakı brauzerləri və onların versiyalarını müəyyən etmək üçün if/elseif konstruksiyasından istifadə edin: Internet Explorer, Opera, Netscape və naməlum tipli brauzer.
  • Brauzer növü və versiya məlumatını massiv kimi qaytarın.
  • opsys_info() funksiyası əməliyyat sisteminin növünü müəyyən edir. Bu dəfə strstr() funksiyasından istifadə olunur, çünki ƏS tipi müntəzəm ifadələrdən istifadə edilmədən müəyyən edilir.
  • Aşağıdakı sistemləri müəyyən etmək üçün if/elseif konstruksiyasından istifadə edin: Windows, Linux, UNIX, Macintosh və naməlum əməliyyat sistemi.
  • Əməliyyat sistemi haqqında məlumatı qaytarın.

Siyahı 8.3. Brauzer növünün və müştəri əməliyyat sisteminin müəyyən edilməsi

Fayl: sniffer.php

Məqsəd: Brauzer növünün/versiyasının və platformasının müəyyən edilməsi

// Funksiya: browser_info

// Məqsəd: Brauzer növünü və versiyasını qaytarır

browser_info funksiyası ($agent) (

// Brauzer növünü təyin edin

// Internet Explorer imzasını axtarın

if (ereg("MSIE (.(1,2))", $agent, $versiya))

$browse_type = "IE";

$browse version = $version;

// Opera imzasını axtarın

elseif (ereg("Opera (.(1,2))". $agent, $versiya)):

$browse_type = "Opera":

$browse_version = $version:

// Netscape imzasını axtarın. Netscape brauzerinin yoxlanılması

// *Internet Explorer və Opera yoxlandıqdan sonra * edilməlidir,

// çünki bütün bu brauzerlər adı bildirməyi xoşlayır

// Mozilla əsl adı ilə birlikdə.

elseif (ereg("Mozilla/(.(1,2))". $agent, $versiya)):

$browse_type = "Netscape";

$browse_version = $version;

// Internet Explorer, Opera və ya Netscape olmadığı halda.

// naməlum brauzer aşkar etdiyimizi bildirir,

$browse_type = "Naməlum";

$browse_version = "Naməlum";

// Brauzer növünü və versiyasını massiv kimi qaytarın

qaytarma massivi ($browse_type, $browse_version);

) // browser_info funksiyasının sonu

// Funksiya: opsys_info

// Məqsəd: İstifadəçinin əməliyyat sistemi haqqında məlumatı qaytarır

funksiya opsys_info($agent) (

// Əməliyyat sistemini müəyyənləşdirin

// Windows imzasını axtarın

if (strstr($agent. "qalib") :

$opsys = "windows";

// Linux imzasını axtarın

elseif (strstr($agent, "Linux")):

$opsys = "Linux";

// UNIX imzasını axtarın

elseif (strstr (Sagent, "Unix")) :

$opsys = "Unix";

// Macintosh imzasını axtarın

elseif (strstr($agent, "Mac")):

$opsys = "Macintosh";

// Naməlum platforma:

$opsys = "Naməlum";

// Əməliyyat sistemi haqqında məlumatı qaytarın

siyahı ($browse_type. $browse_version) = browser_info ($HTTP_USER_AGENT); Soperating_sys = opsysjnfo($HTTP_USER_AGENT);

çap "Brauzer növü: $browse_type
";

çap "Brauzer Versiyası: $browse_version
";

çap "Əməliyyat sistemi: $operating_sys
":

Hamısı budur! Məsələn, əgər istifadəçi Windows kompüterində Netscape 4.75 brauzerindən istifadə edirsə, aşağıdakı çıxış göstərilir:

Brauzer növü: Netscape

Brauzer versiyası: 4.75

Əməliyyat sistemi: Windows

Növbəti fəsildə siz səhifələr arasında keçidi və hətta xüsusi əməliyyat sistemləri və brauzerlər üçün üslub cədvəlləri yaratmağı öyrənəcəksiniz.

Nəticələr

Bu fəsil kifayət qədər çox materialı əhatə edirdi. Əgər mətnlə işləyə bilmirsinizsə, proqramlaşdırma dilinin nə faydası var? Aşağıdakı mövzuları əhatə etdik:

  • POSIX və Perl üslublarında müntəzəm ifadələr haqqında ümumi məlumat;
  • müntəzəm ifadələrlə işləmək üçün standart PHP funksiyaları;
  • xəttin uzunluğunun dəyişdirilməsi;
  • simin uzunluğunu təyin etmək;
  • sətir məlumatlarının emalı üçün alternativ PHP funksiyaları;
  • düz mətni HTML-yə və əksinə çevirmək;
  • sətirlərdə simvolların hərflərinin dəyişdirilməsi.

Növbəti fəsil kitabın ikinci hissəsini açır - yeri gəlmişkən, mənim sevimli. Burada biz PHP-nin Veb-mərkəzli alətlərini tədqiq etməyə başlayacağıq, məzmunun, o cümlədən faylların dinamik şəkildə yaradılması və ümumi şablonların qurulması prosesinə baxacağıq. 2-ci hissənin sonrakı fəsilləri HTML formaları, verilənlər bazaları, sessiya məlumatlarının izlənməsi və qabaqcıl şablon alətləri ilə işləməyi əhatə edir. Orada dayanın - əyləncə başlamaq üzrədir!

Az-çox ciddi oxuyanlar PHP içində çox faydalı bir qlobal massiv olduğunu bilin PHP adlanır $_SERVER. Və bu məqalədə mən bu massivdəki ən populyar açarları və onların dəyərlərini təhlil etmək istərdim, çünki onlar haqqında bilik hətta yeni başlayanlar üçün də məcburidir. PHP proqramçısı.

Başlamazdan əvvəl PHP-də $_SERVER qlobal massivi, Mən sizə dərhal bir az ipucu verəcəyəm. İçərisində əla bir xüsusiyyət var PHP, adlanır phpinfo(). Dərhal onun istifadəsinə bir nümunə verək:

phpinfo();
?>

Bu sadə skriptin icrası nəticəsində siz müxtəlif olan böyük bir cədvəl görəcəksiniz PHP tərcüməçi parametrləri, o cümlədən, sonuna yaxın dəyərlər cədvəli olacaq qlobal massiv $_SERVER. O, bütün açarları və onların bütün müvafiq dəyərlərini sadalayacaq. Bu sizə necə kömək edə bilər? Və fakt budur ki, əgər sizə bu və ya digər dəyər lazımdırsa və açarın nə adlandığını unudursunuzsa, o zaman funksiyadan istifadə edin phpinfo() Adını həmişə xatırlaya bilərsiniz. Ümumiyyətlə, siz bu ssenarini icra edəcəksiniz və məni dərhal başa düşəcəksiniz.

İndi ən populyarına keçək $_SERVER massivinin düymələrinə:

  • HTTP_USER_AGENT- bu açar müştərinin xüsusiyyətlərini öyrənməyə imkan verir. Əksər hallarda, bu, şübhəsiz ki, brauzerdir, lakin həmişə deyil. Yenə də, əgər bu bir brauzerdirsə, hansının olduğunu bu dəyişəndə ​​tapa bilərsiniz.
  • HTTP_REFERER- həmin faylın mütləq yolunu ehtiva edir ( PHP skripti, HTML səhifəsi), biz bu skriptə keçdik. Kobud desək, müştəri haradan gəlib.
  • SERVER_ADDR - IP ünvanı server.
  • REMOTE_ADDR - IP ünvanı müştəri.
  • DOCUMENT_ROOT- saytın kök kataloquna fiziki yol. Bu seçim vasitəsilə təyin edilir Apache server konfiqurasiya faylı.
  • SCRIPT_FILENAME- çağırılan skriptə fiziki yol.
  • QUERY_STRING- sorğu ilə sətir əldə etməyə imkan verən çox faydalı dəyər və sonra bu sətri təhlil edə bilərsiniz.
  • REQUEST_URI- yalnız sorğunun özünü deyil, həm də kökdən çağırılan skriptə nisbi yolu ehtiva edən daha faydalı dəyər. Bu, çox vaxt təkrarlamanı aradan qaldırmaq üçün istifadə olunur index.php, yəni bizdə belə olduqda URL: "http://mysite.ru/index.php"Və" http://mysite.ru/" bir səhifəyə aparın və URL-lər fərqli, dolayısı ilə təkrarlama, axtarış sisteminin optimallaşdırılmasına pis təsir edəcək. Və köməyi ilə REQUEST_URI müəyyən edə bilərik: ilə index.php yoxsa ssenari çağırılmadı. Və biz ilə bir yönləndirmə edə bilərsiniz index.php(əgər o iştirak etsəydi REQUEST_URI) olmadan index.php. Nəticədə belə bir sorğu göndərərkən: " http://mysite.ru/index.php?id=5", bir yönləndirməmiz olacaq URL: "http://mysite.ru/?id=5“Yəni biz təkrarlamadan çıxararaq xilas olduq URL bu index.php.
  • SCRIPT_NAME- çağırılan skriptə nisbi yol.

Bəlkə də bütün bunlar elementlərdir PHP-də $_SERVER qlobal massivi ki, müntəzəm istifadə olunur. Onları bilmək və lazım olanda istifadə etməyi bacarmaq lazımdır.

İkinci dərsdə daha iki dərs yazacağıq və ssenarinin daxili hissəsini tamamilə bitirəcəyik.

Plan

Bu dərslik seriyasının məqsədi istifadəçilərə qeydiyyatdan keçmək, daxil olmaq, sistemdən çıxmaq və parametrləri dəyişmək imkanı verən sadə proqram yaratmaqdır. İstifadəçi haqqında bütün məlumatları ehtiva edəcək sinif User adlanacaq və User.class.php faylında müəyyən ediləcək. Giriş/çıxış üçün cavabdeh olacaq sinif UserTools (UserTools.class.php) adlanacaq.

Bir az sinfin adlandırılması haqqında

Düzgün etiket, sinfi təsvir edən faylları sinfin özü ilə eyni adla adlandırmaqdır. Bu, siniflər qovluğunda hər bir faylın məqsədini təyin etməyi asanlaşdırır.

Sinif fayl adının sonuna .class və ya .inc əlavə etmək də adi haldır. Beləliklə, biz faylın məqsədini aydın şəkildə müəyyən edirik və bu fayllara girişi məhdudlaşdırmaq üçün .htaccess-dən istifadə edə bilərik.

İstifadəçi Sinfi (User.class.php)

Bu sinif hər bir istifadəçini müəyyənləşdirəcək. Bu proqram böyüdükcə "İstifadəçi" anlayışı əhəmiyyətli dərəcədə dəyişə bilər. Xoşbəxtlikdən, OOP proqramlaşdırması əlavə istifadəçi atributları əlavə etməyi asanlaşdırır.

Konstruktor

Bu sinifdə konstruktordan istifadə edəcəyik - bu, sinfin növbəti nüsxəsini yaratarkən avtomatik olaraq çağırılan funksiyadır. Bu, layihə yaradıldıqdan sonra bəzi atributları avtomatik dərc etməyə imkan verir. Bu sinifdə konstruktor tək bir arqument götürəcək: verilənlər bazamızın istifadəçilər cədvəlindən bir sıra ehtiva edən assosiativ massiv.

require_once "DB.class.php"; sinif İstifadəçisi ( ictimai $id; ictimai $username; ictimai $hashedPassword; ictimai $e-poçt;
ictimai $joinDate;
//Yeni obyekt yaradıldıqda konstruktor çağırılır//Arqument kimi DB sətri ilə assosiativ massiv götürür. funksiya __construct($data) ( $this->id = (isset($data["id"])) ? $data["id"] : ""; $this->username = (isset($data[" username"])) ? $data["username"] : ""; $this->hashedPassword = (isset($data["password"])) ? $data["password"] : ""; $this- >email = (isset($data["email"])) ? $data["email"] : "" $this->joinDate = (isset($data["join_date"])) $data[" join_date "] : "";)
ictimai funksiya save($isNewUser = false) ( //yeni verilənlər bazası obyekti yaradın. $db = new DB(); //istifadəçi artıq qeydiyyatdan keçibsə və biz //sadəcə onların məlumatlarını yeniləyirik. if(!$isNewUser) ) ( //məlumat massivini təyin edin $data = array("username" => ""$this->username"", "password" => ""$this->hashedPassword"",
"email" => ""$this->e-poçt"");
//verilənlər bazasındakı sıranı yeniləyin $db->update($data, "istifadəçilər", "id = ".$this->id); )else ( //istifadəçi ilk dəfə qeydiyyatdan keçirilirsə. $data = array("username" => ""$this->username"", "password" => ""$this->hashedPassword"" , "email" => ""$this->e-poçt"", "join_date" => """.date("Y-m-d H:i:s",time()).""" id = $db ->insert($data, "users"); $this->joinDate = time(); ) ) ?>

İzah

Kodun sinif zonasından kənarda olan birinci hissəsi sinfin verilənlər bazasına qoşulmasını təmin edir (çünki İstifadəçi sinfi bu sinfi tələb edən funksiyaya malikdir).

“Qorunan” sinfin dəyişənləri əvəzinə (1-ci dərsdə istifadə olunur) onları “ictimai” kimi təyin edirik. Bu o deməkdir ki, İstifadəçi obyekti ilə işləyərkən sinifdən kənar istənilən kodun bu dəyişənlərə çıxışı var.

Konstruktor cədvəldəki sütunların açar olduğu massiv götürür. Biz $this->variablename istifadə edərək sinif dəyişənini təyin edirik. Bu sinfin nümunəsində biz əvvəlcə müəyyən açarın dəyərinin olub-olmadığını yoxlayırıq. Əgər belədirsə, o zaman sinif dəyişənini həmin qiymətə təyin edirik. Əks halda, boş string. Kod qeydin qısa formasından istifadə edir, əgər:

$dəyər = (3 == 4) ? "A" : "B";

Bu nümunədə 3-ün dördə bərabər olub olmadığını yoxlayırıq! Əgər belədirsə - onda $value = "A", yox - $value = "B". Bizim nümunəmizdə nəticə $value = “B”dir.

İstifadəçilər haqqında məlumatları verilənlər bazasında saxlayırıq

Saxlama funksiyası İstifadəçi obyektindəki cari dəyərlərlə verilənlər bazası cədvəlinə dəyişikliklər etmək üçün istifadə olunur. Bu funksiya ilk dərslikdə yaratdığımız verilənlər bazası sinfindən istifadə edir. Sinif dəyişənlərindən istifadə edərək, $data massivi təyin edilir. Əgər istifadəçi məlumatları ilk dəfə saxlanılırsa, o zaman $isNewUser $true (defolt olaraq yanlış) kimi ötürülür. Əgər $isNewUser = $true olarsa, DB sinifinin insert() funksiyası çağırılır. Əks halda update() funksiyası çağırılır. Hər iki halda istifadəçi obyektindən məlumatlar verilənlər bazasında saxlanılacaq.

Class UserTools.class.php

Bu sinifdə istifadəçilərlə əlaqəli funksiyalar olacaq: login(), logout(), checkUsernameExists() və get(). Ancaq bu tətbiqin genişləndirilməsi ilə siz daha çox şey əlavə edə bilərsiniz.

//UserTools.class.php require_once "User.class.php"; require_once "DB.class.php";
sinif UserTools (
// İstifadəçi daxil olun. Əvvəlcə //istifadəçi adı və parolun verilənlər bazasında bir sıra ilə uyğun olub olmadığını yoxlayır. //Uğurlu olarsa, sessiya dəyişənlərini təyin edin //və istifadəçi obyektini daxilində saxlayın.
ictimai funksiyaya giriş($username, $parol)
{
$hashedPassword = md5($password); $nəticə = mysql_query("SEÇ * FROM istifadəçilərdən istifadəçi adı = "$username" AND password = "$hashedPassword""); if(mysql_num_rows($result) == 1) ( $_SESSION["user"] = serialize(yeni İstifadəçi(mysql_fetch_assoc($result))); $_SESSION["login_time"] = time(); $_SESSION["logged_in "] = 1; doğru qaytarın; )else ( yalanı qaytarın; ) )
// İstifadəçidən çıxın. Sessiya dəyişənlərini məhv edin. ictimai funksiyadan çıxış() ( unset($_SESSION["user"]); unset($_SESSION["login_time"]); unset($_SESSION["logged_in"]); session_destroy(); ) //Yoxlayın olub-olmadığını yoxlayın istifadəçi adı mövcuddur. //Bütün istifadəçi adlarının unikal olmasına əmin olmaq üçün qeydiyyat zamanı çağırılır. ictimai funksiya checkUsernameExists($username) ( $nəticə = mysql_query("istifadəçi adının olduğu istifadəçilərdən identifikatoru seçin="$username""); if(mysql_num_rows($result) == 0) ( false qaytarın; )else( doğrunu qaytarın; )
}
//istifadəçi alın //istifadəçi obyektini qaytarır. İstifadəçi id-sini giriş ictimai funksiyası kimi qəbul edir get($id) ( $db = new DB(); $result = $db->select("users", "id = $id"); new User($result) qaytarın );
?>

login() funksiyası

login() funksiyası adı ilə aydındır. O, $username və $password istifadəçi arqumentlərini götürür və onların uyğunluğunu yoxlayır. Hər şey uyğun gələrsə, bütün məlumatlarla İstifadəçi obyekti yaradır və onu sessiyada saxlayır. Nəzərə alın ki, biz yalnız PHP serialize() funksiyasından istifadə edirik. O, unserialize() funksiyasından istifadə edərək asanlıqla seriyasızlaşdırıla bilən obyektin saxlanılan versiyasını yaradır. Həmçinin, giriş vaxtı qənaət olunacaq. Bundan sonra istifadəçilərə saytda qalma müddəti haqqında məlumat vermək üçün istifadə oluna bilər.

Siz həmçinin qeyd edə bilərsiniz ki, biz $_SESSION["logged_in"] parametrini 1-ə təyin edirik. Bu, istifadəçinin daxil olub-olmadığını hər səhifədə asanlıqla yoxlamağa imkan verir. Yalnız bu dəyişəni yoxlamaq kifayətdir.

çıxış() funksiyası

Həm də sadə bir funksiya. PHP unset() funksiyası yaddaşdakı dəyişənləri təmizləyir, session_destroy() isə sessiyanı silir.

checkUsernameExists() funksiyası

İngilis dilini bilən hər kəs funksiyanı asanlıqla başa düşəcək. Sadəcə olaraq verilənlər bazasından oxşar girişdən istifadə edilib-edilmədiyini soruşur.

get() funksiyası

Bu funksiya istifadəçinin unikal identifikatorunu götürür və DB sinfindən, yəni select() funksiyasından istifadə edərək verilənlər bazasına sorğu edir. O, bir sıra istifadəçi məlumatı olan assosiativ massiv götürəcək və massivi konstruktora ötürərək yeni İstifadəçi obyekti yaradacaq.

Bunu harada istifadə edə bilərəm? Məsələn, xüsusi istifadəçi profillərini göstərməli olan bir səhifə yaratsanız, bu məlumatı dinamik şəkildə əldə etməlisiniz. Bunu belə edə bilərsiniz: (tutaq ki, URL http://www.website.com/profile.php?userID=3 olsun)

//qeyd: əvvəlcə verilənlər bazası bağlantısı açmalı olacaqsınız. //bununla bağlı əlavə məlumat üçün 1-ci hissəyə baxın. //Siz həmçinin sinif fayllarını daxil etdiyinizə əmin olmalısınız.
$tools = yeni UserTools(); $user = $tools->get($_REQUEST["userID"]); echo "İstifadəçi adı: ".$user->username.""; echo "Qoşulma tarixi: ".$user->joinDate."";

Asanlıqla! Doğrudurmu?

Server tərəfində son toxunuş: global.inc.php

global.inc.php saytdakı hər səhifə üçün tələb olunur. Niyə? Bu şəkildə səhifədə ehtiyac duyacağımız bütün adi əməliyyatları yerləşdirəcəyik. Məsələn, biz session_start() funksiyasını işə salacağıq. Verilənlər bazası bağlantısı da açılacaq.

require_once "classes/UserTools.class.php";
require_once "classes/DB.class.php";
// verilənlər bazasına qoşulmaq $db = new DB(); $db->connect();
//UserTools obyektini işə salın $userTools = new UserTools(); //sessiyaya başlayın
session_start();
//girilibsə sessiya dəyişənlərini təzələyin if(isset($_SESSION["logged_in"])) ( $user = serialize($_SESSION["user"]); $_SESSION["user"] = serialize($userTools-> get($user->id) ) ?>

O nə edir?

Burada bir neçə şey baş verir. Əvvəlcə verilənlər bazası ilə əlaqə açırıq.

Qoşulduqdan sonra session_start() funksiyasını işə salırıq. Əgər istifadəçi artıq daxil olubsa, funksiya sessiya yaradır və ya cari sessiyanı davam etdirir. Tətbiqimiz istifadəçilərin daxil olmaq/çıxmaq üçün nəzərdə tutulduğundan, bu funksiya hər səhifədə tələb olunur.

Sonra istifadəçinin daxil olub-olmadığını yoxlayırıq. Əgər belədirsə, ən son istifadəçi məlumatını əks etdirmək üçün $_SESSION["user"] yeniləyəcəyik. Məsələn, istifadəçi öz e-poçtunu dəyişərsə, köhnəsi sessiyada saxlanacaq. Lakin avtomatik yeniləmə ilə bu baş verməyəcək.

Bununla ikinci hissə yekunlaşır! Sabah bu mövzuda son dərsə baxın.

Hər vaxtınız xeyir!

İçindəkilər

$user_info

Bunlar loadUserSettings()-də $user_info üçün müəyyən edilmiş bütün açarlardır. Bəziləri, şübhəsiz ki, özünü izah edir.

qruplar

massiv. Bütün mümkün üzv qrupları da istifadəçiyə qoşulub. Açarların əhəmiyyəti yoxdur. Dəyərlər hər halda int kimi təmizlənmiş qruplardır. Bura daxildir:

  • İbtidai qrup
  • Postların sayı qrupu
  • Əlavə qruplar. Bunlar verilənlər bazasında vergüllə ayrılmış sətir kimi saxlanılır.

possibly_robot

bool. Əgər funksiya aktivdirsə, agent məlum hörümçəyə uyğun gəlirsə və əlil olduqda, savadlı bir təxmin edirsə, doğrudur.

id

int Üzvün verilənlər bazası dəyərinə uyğundur "id_member".!}

istifadəçi adı

ad

simli. Onların göstərilən adı.

e-poçt

passwd

dil

qonaq_dir

is_admin

mövzu

son_giriş

int. Unix vaxt damgası.

ip

$_SERVER["REMOTE_ADDR"]

ip2

$_SERVER["BAN_CHECK_IP"]

yazılar

int. Post sayı.

vaxt_formatı

simli. strtftime() üçün fərdi format.

vaxt_offset

int. İstifadəçinin forum vaxtından saatlıq ofseti.

avatar

  • url: string
  • fayl adı: string
  • custom_dir:bool
  • id_attach: int

smiley_set

mesajlar

int. Onların PM sayı.

oxunmamış_mesajlar

int. Onlarda oxunmamış PM-lərin sayı.

ümumi_daxil olma_zamanı

dostlar

Simli. Onların dostlarının siyahısı vergüllə ayrılmışdır.

laqeydlik lövhələri

Simli. Onların göz ardı etdikləri lövhələrin siyahısı vergüllə ayrılmışdır.

məhəl qoymayan istifadəçilər

Simli. Onların etinasızlıq göstərdiyi istifadəçilərin siyahısı vergüllə ayrılmışdır.

  • SMF 1.1.x-də yalnız PM-lərə məhəl qoyulmur.
  • SMF 2.0.x və sonrakı versiyalarında bu xüsusiyyət nəzərə alınmayan istifadəçinin yazılarını da gizlətmək üçün təkmilləşdirilmişdir.

xəbərdarlıq

int. Onların xəbərdarlıq nöqtələri.

icazələr

query_see_board

Hazırlanmış SQL ifadəsinin bir hissəsi kimi görə biləcəkləri bütün lövhələrin siyahısı.

query_wanna_see_board

Hazırlanmış SQL ifadəsinin bir hissəsi kimi görmək istədikləri lövhələrin siyahısı.

mod_cache

is_mod

Boolean. Üzvün moderator olduğu şuralar istisna olmaqla, yanlışdır. Həmişə təyin olunur.

5 fevral , 2017

Mən heç bir PHP çərçivəsini bilmirəm. Bu, üzücü və utancvericidir, lakin hələ ki, qanunla qadağan olunmayıb. Amma eyni zamanda REST API ilə oynamaq istəyirəm. Problem ondadır ki, php standart olaraq yalnız $_GET və $_POST-u dəstəkləyir. RESTful xidmət üçün siz həmçinin PUT, DELETE və PATCH ilə işləməyi bacarmalısınız. Və kimi bir çox sorğunun mədəni şəkildə necə emal ediləcəyi çox aydın deyil http://site.ru/users ƏLDƏ EDİN, SİLİN http://site.ru/goods/5 və digər ədəbsizliklər. Bütün bu cür sorğuları bir nöqtəyə necə yığmaq, universal olaraq onları hissələrə ayırmaq və məlumatları emal etmək üçün lazımi kodu işə salmaq olar?

Demək olar ki, istənilən PHP çərçivəsi bunu qutudan kənarda edə bilər. Məsələn, marşrutlaşdırmanın aydın və sadə şəkildə həyata keçirildiyi Laravel. Bəs hazırda yeni böyük mövzunu öyrənməyə ehtiyacımız yoxdursa, sadəcə REST API dəstəyi ilə tez bir layihəyə başlamaq istəsək? Bu məqalədə müzakirə olunacaq.

RESTful xidmətimiz nə edə bilməlidir?

1. Bütün 5 əsas sorğu növünü dəstəkləyin: GET, POST, PUT, PATCH, DELETE.
2. Görünüşün müxtəlif marşrutlarını həll edin
POST / mallar
PUT /mallar/(yaxşıId)
GET /users/(userId)/info
və digər özbaşına uzun zəncirlər.

Diqqət: bu məqalə REST API-nin əsasları haqqında deyil
Güman edirəm ki, siz artıq REST yanaşması ilə tanışsınız və onun necə işlədiyini başa düşürsünüz. Əgər belə deyilsə, onda İnternetdə REST-in əsasları ilə bağlı çoxlu gözəl məqalələr var - mən onları təkrarlamaq istəmirəm, mənim fikrim REST ilə necə işləməyi praktikada göstərməkdir.

Hansı funksionallığı dəstəkləyəcəyik?

Gəlin 2 subyekti - məhsullar və istifadəçiləri nəzərdən keçirək.

Məhsullar üçün seçimlər aşağıdakılardır:

  • 1. GET /mallar/(goodId)— Məhsul haqqında məlumat əldə etmək
  • 2. POST / mallar- Yeni məhsul əlavə etmək
  • 3. PUT /mallar/(yaxşıId)- Məhsulu redaktə etmək
  • 4. PATCH /mallar/(yaxşıId)— Bəzi məhsul parametrlərinin redaktə edilməsi
  • 5. SİLİN /mallar/(yaxşıId)- Məhsulun çıxarılması

İstifadəçilər üçün müxtəliflik üçün GET ilə bir neçə variantı nəzərdən keçirək

  • 1. GET /users/(userId)— İstifadəçi haqqında tam məlumat
  • 2. GET /users/(userId)/info— İstifadəçi haqqında yalnız ümumi məlumat
  • 3. GET /users/(userId)/sifarişlər— İstifadəçi sifarişlərinin siyahısı

Bu yerli PHP ilə necə işləyəcək?

Etəcəyimiz ilk şey .htaccess-i qurmaqdır ki, bütün sorğular index.php faylına yönləndirilsin. Məlumatların çıxarılması ilə məşğul olacaq odur.

İkincisi, bizə hansı məlumat lazım olduğuna qərar verək və onu əldə etmək üçün kodu yazaq - index.php.
Bizi 3 növ məlumat maraqlandırır:

  • 1. Sorğu metodu (GET, POST, PUT, PATCH və ya SİL)
  • 2. URL-dən məlumatlar, məsələn, users/(userId)/info - bütün 3 parametr lazımdır
  • 3. Sorğu orqanından məlumatlar
Üçüncüsü, lazımi funksiyaları yerinə yetirən kodu yazacağıq. Funksiyalar fayllara bölünür, hər şey Feng Shui-dir, RESTful xidmət üçün yeni yollar və üsullar əlavə etmək çox sadə olacaq.

.htaccess

Layihə kökündə .htaccess faylı yaradaq

RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteRule ^(.+)$ index.php?q=$1

Bu sirli sətirlərlə sizə bunu etməyi əmr edirik:
1 - istənilən növ sorğuları king-file index.php-ə göndərin
2 - URL-dəki sətri q get parametrində index.php-də mövcud etmək. Yəni, kimi bir URL-dən məlumatlar /users/(userId)/info$_GET["q"]-dan alacağıq.

index.php

index.php-ə sətir-sətir baxaq. Əvvəlcə sorğu metodunu əldə edək.

// Sorğu metodunu təyin edin $method = $_SERVER["REQUEST_METHOD"];

Sonra sorğu orqanından məlumatlar

// Sorğu orqanından məlumat alın $formData = getFormData($metod);

GET və POST üçün müvafiq $_GET və $_POST massivlərindən məlumatları çıxarmaq asandır. Ancaq digər üsullar üçün bir az təhrif etmək lazımdır. Onlar üçün kod axından çıxarılır php://input, kod Google üçün asandır, mən sadəcə ümumi sarğı yazdım - getFormData($method) funksiyası

// Sorğunun əsas funksiyasından verilənlərin alınması getFormData($method) ( // GET və ya POST: verilənləri olduğu kimi qaytarın ($method === "GET") $_GET qaytarın; əgər ($method === "POST" ) return $_POST; // PUT, PATCH və ya DELETE $data = array("&", file_get_contents("php://input") foreach($pair kimi) ( $item = partlatmaq ("=", $pair); əgər (count($item) == 2) ( $data = urldecode($item); ) ) $data;

Yəni getFormData-da bütün detalları gizlətməklə lazımi məlumatları əldə etdik - yaxşı, əla. Ən maraqlı hissəyə - marşrutlaşdırmaya keçək.

// URL-i təhlil edin $url = (isset($_GET["q"])) ? $_GET["q"] : ""; $url = rtrim($url, "/"); $urls = partlatmaq("/", $url);

Yuxarıda öyrəndik ki, .htaccess URL-dən parametrləri $_GET massivinin q-parametrinə yerləşdirəcək. Yəni $_GET["q"] bu kimi bir şey ehtiva edəcək: istifadəçilər/10. Sorğunu yerinə yetirmək üçün hansı üsuldan istifadə etməyimizdən asılı olmayaraq.

A partlatmaq("/", $url) bu sətri bizim üçün artıq işləyə biləcəyimiz seriala çevirir. Beləliklə, istədiyiniz qədər uzun sorğu zəncirləri yaradın, məsələn,
GET /mallar/səhifə/2/limit/10/sort/price_asc
Və arxayın olun, bir sıra alacaqsınız

$urls = massiv("mallar", "səhifə", "2", "limit", "10", "sort", "qiymət_art");

İndi bütün məlumatlarımız var, onunla faydalı bir şey etməliyik. Və sadəcə 4 sətir kod bunu edəcək

// Router və url məlumatını təyin edin $router = $urls; $urlData = massiv_dilim($url, 1); // Router faylını birləşdirin və əsas funksiyanı işə salın include_once "routers/" . $router. ".php"; marşrut($metod, $urlData, $formData);

başa düşürsən? Biz bir obyekti idarə edən faylları yerləşdirdiyimiz marşrutlaşdırıcılar qovluğu yaradırıq: məhsullar və ya istifadəçilər. Eyni zamanda, biz razıyıq ki, faylların adları urlData-da birinci parametrlə üst-üstə düşür - bu, marşrutlaşdırıcı, $ router olacaq. Və bu marşrutlaşdırıcını urlData-dan çıxarmaq lazımdır, bizə artıq ehtiyac yoxdur və yalnız tələb olunan faylı birləşdirmək üçün istifadə olunur. massiv_dilim($url, 1) və birincidən başqa serialın bütün elementlərini bizə verəcəkdir.

İndi yalnız istədiyiniz marşrutlaşdırıcı faylı birləşdirmək və marşrut funksiyasını üç parametrlə işə salmaq qalır. Bu funksiya marşrutu nədir? Gəlin razılaşaq ki, hər bir marşrutlaşdırıcı faylında giriş parametrlərinə əsasən istifadəçinin hansı hərəkəti başlatdığını müəyyən edəcək və tələb olunan kodu yerinə yetirəcək funksiya müəyyən ediləcək. İndi bu daha aydın olacaq. İlk tələbi nəzərdən keçirək - məhsul haqqında məlumat əldə etmək.

GET /mallar/(goodId)

Fayl marşrutlaşdırıcıları/goods.php

// Router funksiyası marşrutu($metod, $urlData, $formData) ( // Məhsul haqqında məlumat əldə etmək // GET /mallar/(goodId) if ($method === "GET" && count($urlData) == = 1) ( // Məhsul identifikatorunu əldə edin $goodId = $urlData; // Məhsulu verilənlər bazasından çıxarın... // Müştəriyə cavabı çıxarın echo json_encode(array("method" => "GET", "id" => $goodId, "yaxşı" => "telefon", "qiymət" => 10000)); error" => "Bad Sorğu") "));

Faylın məzmunu, ötürülən parametrlərdən asılı olaraq lazımi hərəkətləri yerinə yetirən böyük bir marşrut funksiyasıdır. GET metodu və 1 parametr (goodId) urlData-ya ötürülürsə, bu, məhsul haqqında məlumat əldə etmək üçün sorğudur.

Diqqət: nümunə çox sadələşdirilmişdir
Real həyatda, əlbəttə ki, giriş parametrlərini əlavə olaraq yoxlamaq lazımdır, məsələn, goodId rəqəmdir. Kodu buraya yazmaq əvəzinə, yəqin ki, tələb olunan sinfi daxil edəcəksiniz. Məhsulu əldə etmək üçün bu sinifdən bir obyekt yaradın və onun üzərində hansısa metodu çağırın.
Və ya bəlkə nəzarəti artıq lazımi modelləri işə salmağa diqqət yetirəcək bəzi nəzarətçiyə ötürə bilərsiniz. Bir çox variant var, biz yalnız kodun ümumi strukturunu nəzərdən keçiririk.

Müştəriyə cavab olaraq biz lazımi məlumatları göstəririk: məhsulun adı və qiyməti. Məhsul id və metodu real tətbiqdə tamamilə isteğe bağlıdır. Biz onları yalnız düzgün metodun düzgün parametrlərlə çağırıldığından əmin olmaq üçün göstəririk.

Bir nümunə ilə cəhd edək: brauzerinizin konsolunu açın və kodu işə salın

$.ajax((url: "/examples/rest/goods/10", üsul: "GET", dataType: "json", müvəffəqiyyət: function(response)(console.log("cavab:", cavab))) )

Kod oxşar tətbiqi yerləşdirdiyim serverə sorğu göndərəcək və cavab verəcək. Maraqlandığınız marşrutun olduğundan əmin olun /mallar/10 həqiqətən işlədi. Şəbəkə sekmesinde eyni sorğunu görəcəksiniz.
Bəli, /examples/rest bizim test proqramımızın sayta əsas yoludur

Konsolda curl istifadə etməyə daha çox öyrəşmisinizsə, o zaman bunu terminalda işə salın - cavab eyni olacaq və hətta serverin başlıqları ilə.

Curl -X GET https://site/examples/rest/goods/10 -i

Funksiyanın sonunda aşağıdakı kodu yazdıq.

// Səhv başlığını qaytarın("HTTP/1.0 400 Bad Sorğu"); echo json_encode(array("xəta" => "Səhv sorğu"));

Bu o deməkdir ki, parametrlərdə səhv etmişiksə və ya tələb olunan marşrut müəyyən edilməyibsə, müştəriyə 400 Bad Request səhvini qaytaracağıq. Məsələn, URL-ə belə bir şey əlavə edin: mal/10/başqa_param və konsolda bir səhv və 400 cavabı görəcəksiniz - əyri sorğu keçmədi.

Server cavabı ilə http kodları
Fərqli kodları çıxarmaqla narahat olmayacağıq, baxmayaraq ki, bunu REST-ə uyğun etməyə dəyər. Çoxlu müştəri səhvləri var. Sadə vəziyyətimizdə belə, səhv keçən bir üsul üçün 405 uyğun gəlir. Mən hər şeyi qəsdən mürəkkəbləşdirmək istəmirəm.
Uğurlu olarsa, serverimiz həmişə 200 OK qaytaracaq. Xoşbəxtlikdən, resurs yaratarkən 201 Created verməlisiniz. Ancaq yenə də sadələşdirmə baxımından bu incəlikləri atacağıq, lakin real layihədə onları özünüz asanlıqla həyata keçirə bilərsiniz.

Düzünü desəm, məqalə bitdi. Düşünürəm ki, siz artıq yanaşmanı, bütün marşrutların necə həll edildiyini, məlumatların alındığını, necə sınaqdan keçiriləcəyini, yeni sorğuların necə əlavə olunacağını və s. Ancaq təsviri tamamlamaq üçün məqalənin əvvəlində qeyd etdiyimiz qalan 7 sorğunun icrasını verəcəyəm. Yol boyu bir-iki maraqlı şərh yazacam və sonunda mənbə kodu ilə arxivi yerləşdirəcəyəm.

POST / mallar

Yeni məhsulun əlavə edilməsi

// Yeni məhsulun əlavə edilməsi // POST /goods if ($method === "POST" && empty($urlData)) ( // Verilənlər bazasına məhsulun əlavə edilməsi... // Müştəri echo json_encode cavabını çıxarın (array("metod" => "POST", "id" => rand(1, 100), "formData" => $formData));

urlData indi boşdur, lakin formData istifadə olunur - biz sadəcə onu müştəriyə göstərəcəyik.

Bunu necə "doğru" etmək olar?
REST qanunlarına görə, yazı sorğusunda siz yalnız yaradılmış obyektin id-sini və ya bu qurumun əldə edilə biləcəyi url-i qaytarmalısınız. Yəni cavab ya sadəcə bir rəqəm olacaq - (yaxşı), və ya /mallar/(yaxşı kimlik).
Niyə dırnaq içərisində “düzgün” yazdım? Bəli, çünki REST ciddi qaydalar toplusu deyil, tövsiyələrdir. Və bunu necə həyata keçirəcəyiniz üstünlüklərinizdən və ya müəyyən bir layihə üzrə artıq qəbul edilmiş razılaşmalardan asılıdır.
Yadda saxlayın ki, kodu oxuyan və REST yanaşmasından xəbərdar olan başqa bir proqramçı poçt sorğusuna cavab olaraq yaradılmış obyektin id-sini və ya get sorğusu ilə bu obyekt haqqında məlumatların əldə edilə biləcəyi url-ni gözləyəcək.

Konsoldan sınaq

$.ajax((url: "/examples/rest/goods/", üsul: "POST", məlumat: (yaxşı: "notebook", qiymət: 20000), dataType: "json", müvəffəqiyyət: funksiya(cavab)( console.log("cavab:", cavab))))

Curl -X POST https://site/examples/rest/goods/ --data "good=notebook&price=20000" -i

PUT /mallar/(yaxşıId)

Məhsulu redaktə etmək

// Bütün məhsul məlumatlarını yeniləyin // PUT /goods/(goodId) əgər ($metod === "PUT" && count($urlData) === 1) ( // Məhsul identifikatorunu əldə edin $goodId = $urlData; / / Verilənlər bazasındakı bütün məhsul sahələrini yeniləyin... // Müştəriyə cavabı çıxarın echo json_encode(array("metod" => "PUT", "id" => $goodId, "formData" => $formData)) ;

Burada bütün məlumatlar artıq tam istifadə olunur. Məhsul id-si urlData-dan, xassələr isə formData-dan çıxarılır.

Konsoldan sınaq

$.ajax((url: "/examples/rest/goods/15", üsul: "PUT", data: (yaxşı: "notebook", qiymət: 20000), dataType: "json", müvəffəqiyyət: funksiya(cavab) (console.log("cavab:", cavab))

Curl -X PUT https://site/examples/rest/goods/15 --data "good=notebook&price=20000" -i

PATCH /mallar/(yaxşıId)

Qismən məhsul yeniləməsi

// Məhsul məlumatının qismən yenilənməsi // PATCH /goods/(goodId) əgər ($metod === "PATCH" && count($urlData) === 1) ( // Məhsul identifikatorunu əldə edin $goodId = $urlData; // Biz verilənlər bazasında yalnız göstərilən məhsul sahələrini yeniləyirik... // Müştəriyə cavabı çıxarın echo json_encode(array("method" => "PATCH", "id" => $goodId, "formData" => $formData));

Konsoldan sınaq

$.ajax((url: "/examples/rest/goods/15", üsul: "PATCH", data: (qiymət: 25000), dataType: "json", müvəffəqiyyət: function(response)(console.log(" cavab:", cavab))))

Curl -X PATCH https://site/examples/rest/goods/15 --data "qiymət=25000" -i

PUT və PATCH ilə bütün bu şou niyə?
Bir PUT kifayət deyil? Onlar eyni hərəkəti yerinə yetirmirlər - obyektin məlumatlarını yeniləyirlər?
Düzdü - zahirən hərəkət birdir. Fərq ötürülən məlumatlardadır.
PUT serverin göndərildiyini güman edir Hamısı obyekt sahələri və PATCH - yalnız dəyişdi. Sorğu orqanına göndərilənlər. Nəzərə alın ki, əvvəlki PUT-da biz həm məhsulun adını, həm də qiymətini keçdik. Və PATCH-də - yalnız qiymət. Yəni serverə yalnız dəyişdirilmiş məlumatları göndərdik.
PATCH lazımdırmı - özünüz qərar verin. Ancaq yuxarıda qeyd etdiyim o kod oxuyan proqramçı xatırlayın.

SİLİN /mallar/(yaxşıId)

Məhsulun çıxarılması

// Məhsulun silinməsi // DELETE /goods/(goodId) if ($metod === "DELETE" && count($urlData) === 1) ( // Məhsul identifikatorunu əldə edin $goodId = $urlData; // Məhsulu verilənlər bazasından silin... // Müştəriyə cavabı çıxarın echo json_encode(array("metod" => "DELETE", "id" => $goodId));

Konsoldan sınaq

$.ajax((url: "/examples/rest/goods/20", üsul: "DELETE", dataType: "json", müvəffəqiyyət: function(response)(console.log("cavab:", cavab))) )

Curl -X SİL https://site/examples/rest/goods/20 -i

SİL sorğusu ilə hər şey aydındır. İndi istifadəçilərlə işləməyə baxaq - istifadəçilərin marşrutlaşdırıcısı və müvafiq olaraq users.php faylı

GET /users/(userId)

Bütün istifadəçi məlumatlarının alınması. GET sorğusu belə olarsa /istifadəçilər/(userId), sonra əlavə olaraq göstərildiyi təqdirdə istifadəçi haqqında bütün məlumatları qaytaracağıq /info və ya /sifarişlər, sonra, müvafiq olaraq, yalnız ümumi məlumat və ya sifarişlərin siyahısı.

// Router funksiyasının marşrutu($method, $urlData, $formData) ( // İstifadəçi haqqında bütün məlumatların alınması // GET /users/(userId) if ($method === "GET" && count($urlData) = = = 1) ( // Məhsul identifikatorunu əldə edin $userId = $urlData; // İstifadəçi haqqında bütün məlumatları verilənlər bazasından çıxarın... // Müştəriyə cavabı çıxarın echo json_encode(array("method" => " GET", "id" = > $userId, "info" => array("email" => " [email protected]", "name" => "Webdevkin"), "orders" => massiv(array("orderId" => 5, "summa" => 2000, "orderDate" => "01/12/2017"), massiv (" orderId" => 8, "summa" => 5000, "orderDate" => "02/03/2017"))) ) // Səhv başlığını qaytarın("HTTP/1.0 400 Bad Request"); echo json_encode( array("xəta" => "Bad Sorğu"));

Konsoldan sınaq

$.ajax((url: "/examples/rest/users/5", üsul: "GET", dataType: "json", müvəffəqiyyət: function(response)(console.log("cavab:", cavab))) )

Curl -X GET https://site/examples/rest/users/5 -i

GET /users/(userId)/info

İstifadəçi haqqında ümumi məlumat

// İstifadəçi haqqında ümumi məlumatın əldə edilməsi // GET /users/(userId)/info if ($metod === "GET" && count($urlData) === 2 && $urlData === "info") ( / / Məhsul identifikatorunu əldə edin $userId = $urlData // Verilənlər bazasından istifadəçi haqqında ümumi məlumatları çıxarın... // Müştəriyə cavabı çıxarın echo json_encode("method" => "GET", "id" " => $userId, " info" => massiv("email" => " [email protected]", "name" => "Webdevkin"))); qayıt; )

Konsoldan sınaq

$.ajax((url: "/examples/rest/users/5/info", metod: "GET", dataType: "json", uğur: function(cavab)(console.log("cavab:", cavab) )))

Curl -X GET https://site/examples/rest/users/5/info -i

GET /users/(userId)/sifarişlər

İstifadəçi sifarişlərinin siyahısını əldə etmək

// İstifadəçi sifarişlərini qəbul edin // GET /users/(userId)/sifarişlər əgər ($metod === "GET" && count($urlData) === 2 && $urlData === "sifarişlər") ( // Get məhsul id $userId = $urlData // Verilənlər bazasından istifadəçinin sifarişləri haqqında məlumat əldə edin... // Müştəriyə cavabı çıxarın echo json_encode("metod" => "GET", "id" => $ userId, "orders" => massiv("orderId" => 5, "summa" => 2000, "orderDate" => "01/12/2017"), array("orderId" => 8, "summa " => 5000, "orderDate " => "02/03/2017")))); qaytarın; )

Konsoldan sınaq

$.ajax((url: "/examples/rest/users/5/orders", üsul: "GET", dataType: "json", müvəffəqiyyət: function(response)(console.log("cavab:", cavab) )))

Curl -X GET https://site/examples/rest/users/5/orders -i

Nəticələr və mənbələr

Məqalə nümunələrindən qaynaqlar -

Gördüyünüz kimi, yerli php-də REST API dəstəyini təşkil etmək o qədər də çətin deyil və tamamilə qanuni yollarla ortaya çıxdı. Əsas odur ki, marşrutlar və PUT, PATCH və DELETE qeyri-standart PHP üsulları dəstəklənir.

Bu dəstəyi həyata keçirən əsas kod index.php-nin 3 onlarla sətirinə uyğun gəlir. Qalanı sadəcə istədiyiniz şəkildə həyata keçirilə bilən bir qoşqudur. Mən bunu adları layihənizin obyektlərinə uyğun gələn plug-in router faylları şəklində etməyi təklif etdim. Ancaq təxəyyülünüzü işə salıb daha maraqlı bir həll tapa bilərsiniz.



Əlaqədar nəşrlər