php-ում անունների տարածության օգտագործման օրինակներ. Անվանատարածքներ PHP-ում, բացատրված: Անվանատարածքներ. նկարագրության բազմաթիվ շրջանակներ

Վերջերս ես իմ նախագիծը ամփոփեցի անունների տարածքում և հանդիպեցի համապատասխան փաստաթղթերի բացակայության խնդրին: Այն ամենը, ինչ մեզ հաջողվեց գտնել, վերաբերում է մոտավորապես 2009 թվականին, և դա գրեթե 2012 թվականն է... Հայտնաբերված նյութում կան բազմաթիվ ոչ աշխատանքային վայրեր, որոնք օգտագործում են մի բան, որը չկա php-ի ընթացիկ տարբերակում: Այս առումով ես կցանկանայի որոշակի լույս սփռել այս խնդրի վրա:
Այսպիսով, ի՞նչ է Անվանատարածքը կամ անվանատարածքը: Մեծ Վիքիպեդիան դրանք սահմանում է այսպես.

Անվանատարածքը բազմություն է, որը նշանակում է մոդել, վերացական պահեստ կամ միջավայր, որը ստեղծված է եզակի նույնացուցիչների (այսինքն՝ անունների) տրամաբանական խմբավորման համար։ Անվանատարածքում սահմանված նույնացուցիչը կապված է այդ անվանատարածքի հետ: Նույն նույնացուցիչը կարող է ինքնուրույն սահմանվել մի քանի տարածություններում: Այսպիսով, մեկ անվանատարածքում սահմանված նույնացուցիչի հետ կապված արժեքը կարող է (կամ չի կարող) ունենալ նույն (կամ ավելի շուտ տարբեր) նշանակությունը, ինչ նույն նույնացուցիչը, որը սահմանված է մեկ այլ անվանատարածքում: Անվանատարածք տեղյակ լեզուները սահմանում են կանոններ, որոնք ցույց են տալիս, թե որ անվանատարածքին է պատկանում նույնացուցիչը (այսինքն՝ դրա սահմանումը).wiki

Ամեն ինչ պարզ է? Դա իրականում պարզ է: Մինչև 5.3 տարբերակը, php-ում կար ընդամենը երկու բացատ՝ global (որում գործարկվում էր ձեր հիմնական կոդը) և լոկալ (որում սահմանված էին ֆունկցիայի փոփոխականները):

5.3 տարբերակից հետո ամեն ինչ փոխվել է: Այժմ դուք կարող եք սահմանել ձեր անվանատարածքը, որտեղ գոյություն կունենան ձեր դասերը, մեթոդները և այլն:


Հուսով եմ՝ մի փոքր ավելի պարզ դարձավ։

Ես կոնկրետ դասերը նույնն եմ անվանել: Քանի որ դրանք սահմանվում են տարբեր տարածություններում, դրանք երկու տարբեր դասեր են՝ չնայած նույն անուններին: Հիմնական սցենարը դեռ գործում է գլոբալ տարածքում, այստեղ ոչինչ չի փոխվել, և դասերը և գործառույթները դեռ կարող են սահմանվել դրանում։ Այսպիսով, ինչի՞ համար են նախատեսված տարածքները: Առաջին հերթին, որպեսզի համոզվեք, որ երբ դուք ներառում եք ֆայլ ինչ-որ շրջանակով կամ գրադարանով, ձեր դասերը չեն գերազանցի շրջանակի դասերը կամ հակառակը:

Ձեր անվանատարածքում սահմանված դասերն օգտագործելու համար անհրաժեշտ է ճիշտ տեղում ներմուծել ձեր սահմանած տարածությունը գլոբալը (ես սովորաբար նախընտրում եմ դա անել ֆայլի սկզբում): Դա անելու համար օգտագործեք use հիմնաբառը:

Ուշադրություն.ինչ-ինչ պատճառներով php-ն թույլ չի տալիս օգտագործել հիմնաբառը օգտագործելվիճակում բլոկների և օղակների մեջ

Վերցնենք օրինակը նկարներից և իրականացնենք այն կոդով.

Ուշադրություն.անվանատարածքի հիմնաբառը պետք է գտնվի ֆայլի հենց սկզբում՝ անմիջապես հետո
ֆայլ A.php
B.php ֆայլ
Հնարավոր է այլընտրանքային շարահյուսություն.
Առաջարկվում է յուրաքանչյուր անվանատարածք հայտարարել առանձին ֆայլում: Թեև դա հնարավոր է մեկում, այն խստիվ խորհուրդ չի տրվում:
Այժմ անցնենք երրորդ ֆայլին, որում կգործի մեր հիմնական սցենարը
index.php
Թվում է, թե սա առավելություն է, միայն ավելացված է ավելի շատ կոդ, բայց դա ամբողջովին ճիշտ չէ, մի փոքր ավելին ես կտամ autoload դասի օրինակ, որի հետ ֆայլերը դասերի հետ կապող տողերն ավելորդ կլինեն:
Հիմա եկեք նայենք մեր դասերին:

Ուշադրություն.օգտագործելով շրջանակի լուծման օպերատորը (::) php անվանումների տարածքներում չթույլատրված! Միակ բանը, որի համար այն հարմար է, ստատիկ դասի մեթոդներին և հաստատուններին մուտք գործելն է: Սկզբում ցանկանում էին օգտագործել այն անվանատարածքի համար, բայց հետո որոշեցին դեմ լինել՝ ծագած խնդիրների պատճառով։ Հետևաբար, A::A::say(); անվավեր է և կհանգեցնի սխալի:

Անվանատարածքների համար դուք պետք է օգտագործեք «\» հակադարձ նիշը
Ուշադրություն.Թյուրիմացություններից խուսափելու համար անհրաժեշտ է խուսափել այս գրանշանից, երբ օգտագործվում է տողերի մեջ՝ «\\»

Անվանատարածքները կարող են տեղադրվել միմյանց մեջ, եկեք մեր A.php ֆայլին ավելացնենք.
իսկ ինդեքսում կգրենք հետևյալը.

Կարևոր կետը ներմուծվող տարածքների համար փոխանունների օգտագործումն է: Կարող եք գրել A\subA::say(); Դուք կհամաձայնեք, որ դժվար է ամեն անգամ դեպի բացատների ամբողջական ուղիներ գրելը, դրանից խուսափելու համար ներմուծվել են այլանուններ։ Կոմպիլյացիայի ժամանակ տեղի կունենա հետևյալը. sub alias-ի փոխարեն կփոխարինվի A\subA, ուստի մենք կստանանք A\subA::say();

Ի՞նչ է տեղի ունենում այնուհետև, երբ կանչում ենք գլոբալ տարածքում սահմանված գործառույթները: PHP-ն նախ փնտրում է գործառույթ այն տարածքում, որտեղ դուք ներկայումս աշխատում եք, և եթե այն չի գտնում, այն անցնում է գլոբալ շրջանակ: Որպեսզի անմիջապես նշեք, որ դուք օգտագործում եք գլոբալ ֆունկցիա, դուք պետք է դրան նախորդեք հետշեղով:

Տարածքներից դասերի ավտոմատ բեռնման հետ կապված խնդիրներից խուսափելու համար ֆայլային համակարգը պետք է կազմակերպվի այնպես, ինչպես տարածքների կազմակերպումը: Օրինակ, մենք ունենք արմատային թղթապանակ դասեր, որտեղ կպահվեն մեր դասերը, ապա մեր տարածքները կարող են կազմակերպվել հետևյալ կերպ.
classes\A\A.php
classes\A\sub\A.php (ենթատարածությունը կտեղադրվի առանձին ֆայլում)
դասեր\B\B.php

PHP-ն ունի __NAMESPACE__ կախարդական հաստատուն, որը պարունակում է ընթացիկ տարածության անվանումը:

Իսկ հիմա ավտոմատ բեռնման մասին։

Ներքևի դասարանն իմը չէ, ես ուղղակի աշխատեցրի ու մի քիչ բարելավեցի՝ վերցված այստեղից։
Ուշադրություն.Որպեսզի ձեր դասերը բեռնվեն, դասի անունը պետք է համապատասխանի ֆայլի անվանը:

" .$file ."".$filepath)-ում); if (file_exists($filepath)) (if(Autoloader::debug) Autoloader::StPutFile(("միացված" .$filepath));$flag = FALSE; require_once($filepath); break; ) Autoloader::recursive_autoload($file, $path2, &$flag); ) ) closeir($handle); ) ) մասնավոր ստատիկ ֆունկցիա StPutFile($data) ($dir = $_SERVER["DOCUMENT_ROOT"] ." /Log/Log.html"; $file = fopen($dir, "a"); flock($file, LOCK_EX); fwrite($file, ("║" .$data ."=>" .date(" d.m.Y H:i:s") ."

" .PHP_EOL)); flock ($file, LOCK_UN); fclose ($file); ) ) \spl_autoload_register("yourNameSpace\Autoloader::autoload"); )
Եթե ​​նայեք այն դասերի անուններին, որոնք մուտք են գործում բեռնման համար, կտեսնեք, որ յուրաքանչյուր դասի նախորդում է նախածանցը այն անվանատարածքից, որը նշված է օգտագործման մեջ: Ահա թե ինչու ես խորհուրդ եմ տալիս օգտագործել ֆայլերի գտնվելու վայրը դիրեկտորիաներում, որոնք նման են անվանատարածքին, սա արագացնում է որոնումը մինչև մեկ կամ երկու կրկնություններ:

Այժմ մեր ցուցանիշը կարելի է գրել այսպես.
Այժմ բոլոր դասերը և ինտերֆեյսները, որոնք դուք կօգտագործեք, ավտոմատ կերպով կբեռնվեն:

Բացատներով լեզվի որոշ դինամիկ հնարավորություններ ցուցադրելու համար եկեք հայտարարենք մեկ այլ դաս.
test.php

Index.php
sayName ("փորձարկում"); //կամ կարող եք անել այս թեստը\sayName("test2"); //կամ նման $obj::sayName("test"); //կամ կարող եք անել այս թեստը::sayName("test2");

Հուսով եմ, որ իմ հոդվածը օգտակար կլինի ինչ-որ մեկին:

PHP-ն, սկսած 5.3 տարբերակից, մեզ անվանական տարածքներ տվեց: Այդ ժամանակվանից ի վեր որոշակի դանդաղ ու բուռն քննարկումներ են եղել, թե ինչպես օգտագործել այս անվանատարածքը:
Որոշ շրջանակներ, ինչպիսիք են Symphony-ը, Laravel-ը և, իհարկե, Zend-ը, որդեգրել են այս տեխնոլոգիան:
Այս ամենը քիչ թե շատ տեղավորվում է MVC սխեմայի մեջ: Մնում է մեկ, հավանաբար հավերժական բանավեճ՝ ո՞րը պետք է լինի հավելվածի հիմնական ամուսնական զույգը՝ Մոդելն ու Վերահսկիչը։
Ոմանք մեզ ասում են, որ Մոդելը պետք է լինի հաստ ու գեր, իսկ նրա հետ՝ սլացիկ ու նիհար Կառավարիչ: Մի խոսքով` մատրիարխիա:
Մյուսները, ընդհակառակը, կարծում են, որ Վերահսկիչը պետք է կառավարի և հրամայի ամեն ինչ, ուստի նա կուռ է և սնված։ Եվ նրա հետ մի նիհար, սլացիկ Մոդել է, որի խնդիրը եռում է տալ ու բերել։ Սա հայրապետություն է։
Այսպիսով, ո՞րն է ավելի լավ MVC սխեմայում: Պատրիարքությո՞ւն, թե՞ մայրիշխանություն.
Սրան նայենք ժողովրդավարության վրա հիմնված ընտանեկան միավոր կառուցելու տեսանկյունից։ Եվ թող Namespace-ը մեզ օգնի այս հարցում:

Մենք չենք սիրում հաստ ու կոպիտ Կարգավորիչներ, որոնք, ինչպես ցուլը չինական խանութում, կարող են ջախջախել ամբողջ հավելվածը, եթե դուք անզգույշ եք:
Մենք էլ չենք սիրում գեր Մոդելներ։ Դե, ով է սիրում դրանք: Նրանք պետք է արժանի լինեն ամբիոնին։
Փորձենք Namespace-ի օգնությամբ, ինչպես լավ խնկավաճառի հետ, ստեղծել ներդաշնակ ընտանիք։

Նախ, եկեք ստեղծենք հավելվածի շրջանակը: Ինչքան էլ բանական լինի, թող բլոգ լինի։

Մենք ստեղծել ենք հիմնական կառուցվածք, որտեղ.

  • Բլոգը մեր հավելվածի պահեստն է.
  • Դիտումներ և կաղապարներ - դիտումների և ձևանմուշների պահպանում;
  • Կոմունալ - ընդհանուր գրադարանների պահեստ;
  • index.php - bootstrap script;
  • Պոստ - այստեղ պետք է տեղի ունենա Վերահսկիչի և Մոդելի ընտանեկան իդիլիան:

index.php-ով ամեն ինչ պարզ է.

run(); /* * index.php-ի վերջ */

Մենք որոշում ենք անհրաժեշտ ուղիները և ստեղծում ենք ավտոբեռնիչ:
Ավտոբեռնիչը բեռնում է պահանջվող դասերը, որոնք գտնվում են թղթապանակի հիերարխիայում՝ ըստ դասի անվանատարածքի: Օրինակ, BlogPostServicesView դասը կփնտրվի Blog/Post/Services-ում:
Եվ ահա Namespace-ի հետ առաջին հանդիպումը։
Երբ մենք սկսում ենք index.php, մենք ստեղծում ենք Blog հավելվածի օրինակ, որի դասը բեռնված է Blog/Blog.php-ից։
Եկեք նայենք նրան:

գրառում = նոր գրառում (); ) հանրային գործառույթ run() ( $this->post->view->all(); ) )//end class Բլոգ

Blog դասը ստեղծելիս մենք դրա մեջ ներարկում ենք Post դաս Անվանատարածք BlogPost-ով, և ավտոմատ բեռնիչը այն բեռնում է Blog/Post/Post.php-ից:
Հավանաբար այս դասը կարելի է անվանել Controller,

դիտում = նոր տեսք (); ) )//վերջ դասարան Փոստ

Փոստային կազմակերպությունը ներառում է.
- ինքնին տվյալների գրառման կառուցվածքը - BlogPostEntitiesPostEntity.php

Վերահսկիչի հարցումները սպասարկող ծառայություններ - BlogPostServicesView.php (ծառայություններից մեկը, օրինակ)

db = նոր DB (); )//վերջ __կառուցել հանրային ֆունկցիա all() ( $posts = $this->db->survey(); Contemplate::compose(array("header" => "header", "main" => "main", "footer" => "footer",), array ("posts" => $posts, "title" => "Viper site")); ) )//վերջ դասի PostView

Տվյալների բազայի փոխազդեցության համակարգը - BlogPostRepositoriesDB.php - ահա այն, մեր բարակ, էլեգանտ մոդելը,
Պարզապես տվեք, բերեք, և ոչ ավելին:

dbh = նոր PDO ("mysql:host=localhost;dbname=test", $user, $pass, զանգված (PDO::ATTR_PERSISTENT => ճշմարիտ)); ) catch (PDOException $e) ( echo "Error!: " . $e->getMessage() ."
"; die(); ) )//end __կառուցել հանրային ֆունկցիայի հարցում() ( $query_view = $this->dbh->prepare("SELECT * հաղորդագրություններից"); $query_view->execute(); վերադարձնել $query_view- >fetchAll(PDO::FETCH_CLASS, «BlogPostEntitiesPostEntity»); )//վերջ հարցումը)//վերջ դասի Db

Արդյունքում մենք կարողացանք ստեղծել հավելվածի կառուցվածք, որտեղ բոլոր բաղադրիչները լավ միացված են, մինչդեռ հասանք դասերի հստակ տարանջատման, որտեղ յուրաքանչյուր դաս կատարում է իր առաջադրանքը: Մեր կարգավորիչը բարակ է և միևնույն ժամանակ հզոր: Մոդելը համապատասխանում է նրան։ Կատարյալ ընտանիք!
Եվ այս ամենը շնորհիվ Անվանատարածքի:

Չեմ վիճում, շատ դեպքերում շրջանակը հարմար է։ Բայց տեսեք, Անունների տարածքը ձեզ ոչինչ չի՞ հիշեցնում:
Դասերի հստակ բաժանում, դիրեկտորիաների և դասերի խիստ և միևնույն ժամանակ ճկուն հիերարխիա, որը լիովին ենթակա է մշակողին:
Երբեմն նման նշանակալի հավելում չկա հարյուրավոր ֆայլերի և դասերի տեսքով՝ շրջանակի տեսքով։
Դասերի և բաղադրիչների փոխազդեցության կանոնների Պրոկրուստեի անկողնու բացակայություն:

Հոդվածը ոգեշնչվել է այս թեմայի շուրջ մտքերից՝ Թեյլոր Օթվելի՝ Laravel շրջանակի հեղինակի կողմից, ինչի համար շատ շնորհակալ եմ նրան:
Օրինակի սկզբնական կոդի հասցեն GitHub-ում:

Բարեւ Ձեզ. Այսօրվա հոդվածում մենք կանդրադառնանք. ինչ են անվանումների տարածքները PHP-ում.

Եթե ​​երկար ժամանակ եք օգտագործում այն OOP, ապա դուք հավանաբար հանդիպել եք մի իրավիճակի, երբ երրորդ կողմի գրադարանը միացնելիս ձախողվել եք այն փաստի պատճառով, որ դուք արդեն օգտագործում եք նույն դասի անունները ձեր ծածկագրում, ինչ գրադարանում: Սա հատկապես կարող է տեղի ունենալ, եթե դուք օգտագործում եք սովորական անուններ, ինչպիսիք են «մոդել», «db»եւ այլն։ Ես ձեզ հիմա կասեմ, թե ինչպես դա շտկել:

Անվան տարածություն- սա մի տեսակ պահեստ է, որը ստեղծված է եզակի նույնացուցիչների (անունների) վերացական խմբավորման համար:

Նրանք. եթե օգտագործում եք անունների տարածքներ, ապա դուք կարող եք ապահով կերպով միացնել երրորդ կողմի գրադարանները և չվախենալ, որ դրանք կունենան նույն անունները, ինչ ձեր կոդը: Եկեք ավարտենք տեսությունը և անցնենք պրակտիկային:

Եկեք ստեղծենք ֆայլ myclass.phpայս բովանդակությամբ

անվանատարածք my\oneProject;
դաս MyClass ( )
?>

Այստեղ մենք անվանատարածքում դաս ենք ստեղծել my\oneProject. Ի դեպ, պետք է գրել հենց հետին կտրվածքը։ Մի շփոթվեք։

Այժմ ֆայլում index.phpգրենք հետեւյալը

require_once ("myclass.php");
$mc = նոր MyClass(); // Սխալ. դասը չի գտնվել
$mc = նոր my\oneProject\MyClass(); // ամեն ինչ աշխատում է
?>

Ինչպես տեսնում եք, այժմ հնարավոր չէ հենց այնպես դաս ստեղծել, դուք պետք է նշեք, թե որում անվանատարածքնա պառկած է։

Կարող ենք միանգամից մի քանիսը նշել անունների տարածքներմեկ ֆայլում

անվանատարածքի նախագիծ;

Const CONNECT_OK = 1;
դասի միացում ()
միացում () ()

ԱնվանատարածքՄեկ այլ նախագիծ;

Const CONNECT_OK = 1;
դասի միացում ()
միացում () ()
?>

Չնայած այն հանգամանքին, որ մենք ունենք դասերի, ֆունկցիաների և հաստատունների բացարձակապես նույնական անուններ, մենք չենք ունենա անունների կոնֆլիկտ, քանի որ. նրանք պառկած են տարբեր տարածություններում:

Մենք կարող ենք նաև օգտագործել փակագծերի շարահյուսություն։

Անվան տարածության նախագիծ (

Const CONNECT_OK = 1;
դասի միացում ()
միացում () ()
}

Անվանատարածք AnotherProject (

Const CONNECT_OK = 1;
դասի միացում ()
միացում () ()
}
?>

Եթե ​​դուք միավորում եք կոդը մեջ գլոբալ անվանումների տարածությունկոդով այլ տարածություններում, ապա օգտագործվում է միայն փակագծերով շարահյուսությունը։

Անվան տարածության նախագիծ (

Const CONNECT_OK = 1;
դասի միացում ()
միացում () ()
}

Անվան տարածություն ( // գլոբալ կոդը
նիստ_սկիզբ ();
$a = Project\connect();
echo Project\Connection::start();
}
?>

Նաև մի մոռացեք, որ անվանատարածք սահմանելը միշտ պետք է լինի կոդի առաջին տողը: Եթե ​​այսպես գրես, սխալ կլինի

Պարզելու համար, թե որ անվանատարածքում եք դուք ներկայումս, կարող եք օգտագործել հաստատունը __NAMESPACE__

անվանատարածքի նախագիծ;
echo """, __NAMESPACE__, """; // տպելու է «Նախագիծ»
?>

Օգտագործելով այս հաստատունը, դուք կարող եք, օրինակ, դինամիկ կերպով կառուցել անուններ

անվանատարածքի նախագիծ;

Գործառույթը ներառում է ($classname) (
$a = __NAMESPACE__: «\\»: $classname;
վերադարձնել նոր $a;
}
?>

Այսպիսով, այսօրվա համար այսքանը: Դուք կարող եք ավելի շատ տեղեկատվություն և գործնական գիտելիքներ ստանալ՝ մասնակցելով դասընթացին

Վերջերս ես իմ նախագիծը ամփոփեցի անունների տարածքում և հանդիպեցի համապատասխան փաստաթղթերի բացակայության խնդրին: Այն ամենը, ինչ մեզ հաջողվեց գտնել, վերաբերում է մոտավորապես 2009 թվականին, և դա գրեթե 2012 թվականն է... Հայտնաբերված նյութում կան բազմաթիվ ոչ աշխատանքային վայրեր, որոնք օգտագործում են մի բան, որը չկա php-ի ընթացիկ տարբերակում: Այս առումով ես կցանկանայի որոշակի լույս սփռել այս խնդրի վրա:
Այսպիսով, ի՞նչ է Անվանատարածքը կամ անվանատարածքը: Մեծ Վիքիպեդիան դրանք սահմանում է այսպես.

Անվանատարածքը բազմություն է, որը նշանակում է մոդել, վերացական պահեստ կամ միջավայր, որը ստեղծված է եզակի նույնացուցիչների (այսինքն՝ անունների) տրամաբանական խմբավորման համար։ Անվանատարածքում սահմանված նույնացուցիչը կապված է այդ անվանատարածքի հետ: Նույն նույնացուցիչը կարող է ինքնուրույն սահմանվել մի քանի տարածություններում: Այսպիսով, մեկ անվանատարածքում սահմանված նույնացուցիչի հետ կապված արժեքը կարող է (կամ չի կարող) ունենալ նույն (կամ ավելի շուտ տարբեր) նշանակությունը, ինչ նույն նույնացուցիչը, որը սահմանված է մեկ այլ անվանատարածքում: Անվանատարածք տեղյակ լեզուները սահմանում են կանոններ, որոնք ցույց են տալիս, թե որ անվանատարածքին է պատկանում նույնացուցիչը (այսինքն՝ դրա սահմանումը).wiki

Ամեն ինչ պարզ է? Դա իրականում պարզ է: Մինչև 5.3 տարբերակը, php-ում կար ընդամենը երկու բացատ՝ global (որում գործարկվում էր ձեր հիմնական կոդը) և լոկալ (որում սահմանված էին ֆունկցիայի փոփոխականները):

5.3 տարբերակից հետո ամեն ինչ փոխվել է: Այժմ դուք կարող եք սահմանել ձեր անվանատարածքը, որտեղ գոյություն կունենան ձեր դասերը, մեթոդները և այլն:


Հուսով եմ՝ մի փոքր ավելի պարզ դարձավ։

Ես կոնկրետ դասերը նույնն եմ անվանել: Քանի որ դրանք սահմանվում են տարբեր տարածություններում, դրանք երկու տարբեր դասեր են՝ չնայած նույն անուններին: Հիմնական սցենարը դեռ գործում է գլոբալ տարածքում, այստեղ ոչինչ չի փոխվել, և դասերը և գործառույթները դեռ կարող են սահմանվել դրանում։ Այսպիսով, ինչի՞ համար են նախատեսված տարածքները: Առաջին հերթին, որպեսզի համոզվեք, որ երբ դուք ներառում եք ֆայլ ինչ-որ շրջանակով կամ գրադարանով, ձեր դասերը չեն գերազանցի շրջանակի դասերը կամ հակառակը:

Ձեր անվանատարածքում սահմանված դասերն օգտագործելու համար անհրաժեշտ է ճիշտ տեղում ներմուծել ձեր սահմանած տարածությունը գլոբալը (ես սովորաբար նախընտրում եմ դա անել ֆայլի սկզբում): Դա անելու համար օգտագործեք use հիմնաբառը:

Ուշադրություն.ինչ-ինչ պատճառներով php-ն թույլ չի տալիս օգտագործել հիմնաբառը օգտագործելվիճակում բլոկների և օղակների մեջ

Վերցնենք օրինակը նկարներից և իրականացնենք այն կոդով.

Ուշադրություն.անվանատարածքի հիմնաբառը պետք է գտնվի ֆայլի հենց սկզբում՝ անմիջապես հետո
ֆայլ A.php
B.php ֆայլ
Հնարավոր է այլընտրանքային շարահյուսություն.
Առաջարկվում է յուրաքանչյուր անվանատարածք հայտարարել առանձին ֆայլում: Թեև դա հնարավոր է մեկում, այն խստիվ խորհուրդ չի տրվում:
Այժմ անցնենք երրորդ ֆայլին, որում կգործի մեր հիմնական սցենարը
index.php
Թվում է, թե սա առավելություն է, միայն ավելացված է ավելի շատ կոդ, բայց դա ամբողջովին ճիշտ չէ, մի փոքր ավելին ես կտամ autoload դասի օրինակ, որի հետ ֆայլերը դասերի հետ կապող տողերն ավելորդ կլինեն:
Հիմա եկեք նայենք մեր դասերին:

Ուշադրություն.օգտագործելով շրջանակի լուծման օպերատորը (::) php անվանումների տարածքներում չթույլատրված! Միակ բանը, որի համար այն հարմար է, ստատիկ դասի մեթոդներին և հաստատուններին մուտք գործելն է: Սկզբում ցանկանում էին օգտագործել այն անվանատարածքի համար, բայց հետո որոշեցին դեմ լինել՝ ծագած խնդիրների պատճառով։ Հետևաբար, A::A::say(); անվավեր է և կհանգեցնի սխալի:

Անվանատարածքների համար դուք պետք է օգտագործեք «\» հակադարձ նիշը
Ուշադրություն.Թյուրիմացություններից խուսափելու համար անհրաժեշտ է խուսափել այս գրանշանից, երբ օգտագործվում է տողերի մեջ՝ «\\»

Անվանատարածքները կարող են տեղադրվել միմյանց մեջ, եկեք մեր A.php ֆայլին ավելացնենք.
իսկ ինդեքսում կգրենք հետևյալը.

Կարևոր կետը ներմուծվող տարածքների համար փոխանունների օգտագործումն է: Կարող եք գրել A\subA::say(); Դուք կհամաձայնեք, որ դժվար է ամեն անգամ դեպի բացատների ամբողջական ուղիներ գրելը, դրանից խուսափելու համար ներմուծվել են այլանուններ։ Կոմպիլյացիայի ժամանակ տեղի կունենա հետևյալը. sub alias-ի փոխարեն կփոխարինվի A\subA, ուստի մենք կստանանք A\subA::say();

Ի՞նչ է տեղի ունենում այնուհետև, երբ կանչում ենք գլոբալ տարածքում սահմանված գործառույթները: PHP-ն նախ փնտրում է գործառույթ այն տարածքում, որտեղ դուք ներկայումս աշխատում եք, և եթե այն չի գտնում, այն անցնում է գլոբալ շրջանակ: Որպեսզի անմիջապես նշեք, որ դուք օգտագործում եք գլոբալ ֆունկցիա, դուք պետք է դրան նախորդեք հետշեղով:

Տարածքներից դասերի ավտոմատ բեռնման հետ կապված խնդիրներից խուսափելու համար ֆայլային համակարգը պետք է կազմակերպվի այնպես, ինչպես տարածքների կազմակերպումը: Օրինակ, մենք ունենք արմատային թղթապանակ դասեր, որտեղ կպահվեն մեր դասերը, ապա մեր տարածքները կարող են կազմակերպվել հետևյալ կերպ.
classes\A\A.php
classes\A\sub\A.php (ենթատարածությունը կտեղադրվի առանձին ֆայլում)
դասեր\B\B.php

PHP-ն ունի __NAMESPACE__ կախարդական հաստատուն, որը պարունակում է ընթացիկ տարածության անվանումը:

Իսկ հիմա ավտոմատ բեռնման մասին։

Ներքևի դասարանն իմը չէ, ես ուղղակի աշխատեցրի ու մի քիչ բարելավեցի՝ վերցված այստեղից։
Ուշադրություն.Որպեսզի ձեր դասերը բեռնվեն, դասի անունը պետք է համապատասխանի ֆայլի անվանը:

" .$file ."".$filepath)-ում); if (file_exists($filepath)) (if(Autoloader::debug) Autoloader::StPutFile(("միացված" .$filepath));$flag = FALSE; require_once($filepath); break; ) Autoloader::recursive_autoload($file, $path2, &$flag); ) ) closeir($handle); ) ) մասնավոր ստատիկ ֆունկցիա StPutFile($data) ($dir = $_SERVER["DOCUMENT_ROOT"] ." /Log/Log.html"; $file = fopen($dir, "a"); flock($file, LOCK_EX); fwrite($file, ("║" .$data ."=>" .date(" d.m.Y H:i:s") ."

" .PHP_EOL)); flock ($file, LOCK_UN); fclose ($file); ) ) \spl_autoload_register("yourNameSpace\Autoloader::autoload"); )
Եթե ​​նայեք այն դասերի անուններին, որոնք մուտք են գործում բեռնման համար, կտեսնեք, որ յուրաքանչյուր դասի նախորդում է նախածանցը այն անվանատարածքից, որը նշված է օգտագործման մեջ: Ահա թե ինչու ես խորհուրդ եմ տալիս օգտագործել ֆայլերի գտնվելու վայրը դիրեկտորիաներում, որոնք նման են անվանատարածքին, սա արագացնում է որոնումը մինչև մեկ կամ երկու կրկնություններ:

Այժմ մեր ցուցանիշը կարելի է գրել այսպես.
Այժմ բոլոր դասերը և ինտերֆեյսները, որոնք դուք կօգտագործեք, ավտոմատ կերպով կբեռնվեն:

Բացատներով լեզվի որոշ դինամիկ հնարավորություններ ցուցադրելու համար եկեք հայտարարենք մեկ այլ դաս.
test.php

Index.php
sayName ("փորձարկում"); //կամ կարող եք անել այս թեստը\sayName("test2"); //կամ նման $obj::sayName("test"); //կամ կարող եք անել այս թեստը::sayName("test2");

Հուսով եմ, որ իմ հոդվածը օգտակար կլինի ինչ-որ մեկին:

(PHP 5 >= 5.3.0, PHP 7)

Նախքան անվանատարածքների օգտագործումը քննարկելը, կարևոր է հասկանալ, թե ինչպես է PHP-ն իմանում, թե որ անվանատարածքի տարրն է ձեր կոդը պահանջում: Պարզ անալոգիա կարելի է անել PHP անվանատարածքների և ֆայլային համակարգի միջև: Ֆայլային համակարգում ֆայլ մուտք գործելու երեք եղանակ կա.

  1. Ֆայլի հարաբերական անունը նման է foo.txt. Սա լուծում է ընթացիկ տեղեկատու/foo.txtորտեղ ընթացիկ գրացուցակը ներկայումս զբաղեցված գրացուցակն է: Այսպիսով, եթե ընթացիկ գրացուցակը /տուն/foo, անունը որոշում է /home/foo/foo.txt.
  2. Հարաբերական ուղու անունը նման է ենթատեղեկատու/foo.txt. Սա լուծում է currentdirectory/subdirectory/foo.txt.
  3. Բացարձակ ուղու անուն /main/foo.txt. Սա լուծում է /main/foo.txt.
Նույն սկզբունքը կարող է կիրառվել PHP-ի անվանատարածքի տարրերի նկատմամբ։ Օրինակ, դասի անունը կարելի է հիշատակել երեք եղանակով.
  1. Չորակված անուն կամ դասի աննախածանց անուն $a = new foo();կամ foo::staticmethod(); ընթացիկ անունների տարածություն, սա լուծում է ներկայիս անունների տարածություն\foo foo. Մի նախազգուշացում. ֆունկցիաների և հաստատունների չորակված անունները կվերածվեն գլոբալ ֆունկցիաների և հաստատունների, եթե անունների տարածության ֆունկցիան կամ հաստատունը սահմանված չէ: Մանրամասների համար տե՛ս Անվանատարածքների օգտագործում. վերադարձ դեպի գլոբալ ֆունկցիա/հաստատուն:
  2. Որակավորված անուն կամ դասի նախածանցով անուն $a = նոր ենթաանուն\foo();կամ subnamespace\foo::staticmethod();. Եթե ​​ներկայիս անվանատարածքն է ընթացիկ անունների տարածություն, սա լուծում է currentnamespace\subnamespace\foo. Եթե ​​կոդը գլոբալ է, ոչ անվանատարածքի կոդ, ապա դա լուծում է subnamespace\foo.
  3. Լիովին որակավորված անուն կամ գլոբալ նախածանցով օպերատորի նման նախածանցով անուն $a = new \currentnamespace\foo();կամ \currentnamespace\foo::staticmethod();. Սա միշտ լուծում է կոդում նշված բառացի անվանը, ներկայիս անունների տարածություն\foo.

Ահա փաստացի կոդում երեք տեսակի շարահյուսության օրինակ.

անունների տարածություն Foo\Bar\subnamespace;

const FOO = 1;
ֆունկցիա foo()()
դասի սնունդ
{
}
?>

անվանատարածք Foo\Bar;
ներառել «file1.php»;

const FOO = 2;
ֆունկցիա foo()()
դասի սնունդ
{
ստատիկ ֆունկցիա staticmethod()()
}

/* Անհայտ անուն */
foo (); foo::staticmethod(); echo FOO;

/* Որակավորված անուն */
subnamespace\foo(); // որոշում է գործառույթը Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // որոշում է դասի Foo\Bar\subnamespace\foo,
// մեթոդ ստատիկ մեթոդ
echo subnamespace\FOO; // լուծում է մշտական ​​Foo\Bar\subnamespace\FOO

/* Լիովին որակավորված անուն */
\foo\bar\foo(); // որոշում է գործառույթը Foo\Bar\foo
\foo\Bar\foo::staticmethod(); // որոշում է դասի Foo\Bar\foo, մեթոդ staticmethod
echo\Foo\Bar\FOO; // լուծում է մշտական ​​Foo\Bar\FOO
?>

Նկատի ունեցեք, որ ցանկացած գլոբալ դասի, ֆունկցիայի կամ հաստատուն մուտք գործելու համար կարող է օգտագործվել լիովին որակավորված անուն, օրինակ \strlen()կամ \Բացառությունկամ \INI_ALL. ?>