Autor Zpráva
valecekm
Profil
Dobry den. Chtel bych se zeptat zkusenejsich PHP programatoru, jak vyresit jeden zajimavej problem. Jde o require v cyklu. Potreboval jsem pripojit vice souboru z jedne slozky abych nemusel do skriptu psat stopadesatkrat require kazdeho souboru a tim padem aby to bylo pouzitelne v tom pripade, kdyby nekdy v budoucnu bylo potreba pripojit dalsi sb., tak abych nemusel prepisovat vsechny sb. a psat do kazdeho dalsi a dalsi require(u vetsich projektu nepredstavitelna a silena vec). Podle meho usudku se vzdy pripoji pouze posledni nacteny soubor ze slozky a predesle nikoli. Lepsi bude asi ukazka skriptu:

<?php
function Require_FILE(){

$cesta="require_file"; // cesta k souborum
$slozka = dir($cesta); 

// pole podporovanych pripon souboru
$pole_pripon=array('php','inc','PHP','INC');
$pole_souboru = array(); // vytvori zatim prazdne pole pro soubory

//// NACTENI SOUBORU A ULOZENI DO POLE ////
//----------------------------------------------------------

while($soubor=$slozka->read()) /* precte soubory ve slozce */{
  if ($soubor=="." || $soubor=="..") continue; // vylouci stejny a nadrazeny adresar 
$soubor_n = explode(".",  $soubor); // rozdeli priponu a nazev souboru do pole
$pripona = $soubor_n[1]; // pripona souboru
    foreach($pole_pripon as $pripona_z) // prohledani pole pripon
    {
// kontrola souboru jestli je soubor povoleny soubor pro vlozeni (podle pripony)
if ($pripona==$pripona_z){$pole_souboru[] = $cesta."/".$soubor;} // ulozi sb. do pole    
  }
 } 

sort($pole_souboru); // seradi prvky v poli pole nazvu(cisla na zacatku)
$prvku_v_poli = count($pole_souboru)-1; // pocet prvku v poli

//// POKUS O PRIPOJENI SOUBORU ////
//----------------------------------------------

for ($i=0; $i<=$prvku_v_poli; $i++) {
	${'req_i'.$i} = $pole_souboru[$i];
	require ${'req_i'.$i};/*echo '$req_i'."$i";}*/
 }
}
Require_FILE();
?>


Zkousel jsem primo i:

<?php
/*
.
. cast 1
.
*/
require $pole_souboru[$i];

// nebo i 
require "$pole_souboru[$i]";
/*
.
. cast 2
.
*/
?>

Ovsem marne a bez vysledku. Kdyby nekdo vedel kde je chyba nebo co to dela, ci jak to vyresit, byl bych strasne rad. Nebranil bych se i neceho z objektovyho prog. pokud by to nejak slo. Dival jsem se na autoload, ale nejak jsem to pochopil tak, ze tam se nahravaji pouze automaticky tridy dane AP a nikoli obyc soubory.
Alphard
Profil
Místo require $pole_souboru[$i]; dejte třeba echo $pole_souboru[$i]; a zkontrolujte, jestli jsou správné cesty.
Také si dejte pozor, abyste se nezamotal v platnosti kódu, nejsem si úplně jist chováním, ale načítání globálnío kódu ve funkci možná nebude nejšťastnější řešení, ale nevím. Spíš bych šel cestou nějakého init.php souboru, který by se jednoduše includoval v každém (hlavním) scriptu, to by mělo být bez problémů.
valecekm
Profil
Alphard
Cesty jsou opravdu spravne.

Spíš bych šel cestou nějakého init.php souboru, který by se jednoduše includoval v každém (hlavním) scriptu

Nevim jestli jsem to zpravne pochopil, ale pokud myslite nahrani vseho duleziteho do jednoho souboru a ten pote pripojovat, tak tohle neni to nejlepsi reseni. Porad a stale potom jde o prepisovani a pridavani require v budoucnosti. Vypisi echo probihaj opravdu vporadku a i dokonce kdyz sme kontroloval v programu ktery sb. se pripojuje, tak to sedelo. Problem je vtom ze se pripoji vzdy az ten posledni kdyz cyklus skonci, predesle ne. Ovsem kdyz to vypisu echo, tak se vypisi vsechny. Akorat require se pripoji az ten posledni :-( .Fakt nevim a nechapu to...
valecekm
Profil
Zdravím všechny, omlouvám se moderátorům, že obnovuji tímto toto již staré téma, ale podle mně je furt lepší obnovit toto staré, než zakládat nové duplicitní, protože tento problém zatím nebyl zcela vyřešen a znovu bych se o tomto problému s někým pobavil a probral ho, poněvadž to potřebuji vyřešit. Od výše uvedeného jsem upustil, ale teď nedávno jsem se k tomu musel uchýlit. Tento problém ještě více zamotám a to tím, že když připojuji soubory, ve kterých jsou nějaké fce, tak tyto fce jsou pak normálně dostupné(v šabloně do které připojuji), tudíž cyklus for pravděpodobně opravdu připojí všechny soubory(problém již není jako výše), ovšem s tím rozdílem, že dostupné jsou jen fce uvnitř těchto souborů, ale né proměnné.
Zjednodušeně př. připojování ve funkci Require_FILE()->v cyklu for:

soubor1.php - obsah: fce() - dostupné v šabloně ; $prom./echo $prom. - nedostupné v šabloně/vypíše se v připojovaném souboru ve kterém prom. je
soubor2.php - obsah: fce() - dostupné... ; $prom./echo $prom. - nedostupné.../vypíše se v připojovaném...
soubor3.php - obsah: fce() - dostupné... ; $prom./echo $prom. - nedostupné.../vypíše se v připojovaném...

Prom., uvnitř připojovaných souborů se tudíž ocitají prakticky ve funkci a nejsou dostupné z venčí, tak bych se chtěl zeptat, jestli by šel nějaký způsob, že by se všechny prom. v této funkci nastavily jako globální, aniž bych u každé musel sólo definovat že má být globální(nějaký univerzální způsob zápisu...všechny prom. ve fci globální bez ohledu na název.(tečka))? Pokud se stím někdo již setkal samozřejmě. Kdyby to bylo nadefinování pár prom. jako globálních, tak bych to samozřejmě neřešil, ale jedná se o dosti velmi rozsáhlý systém s mnoha prom., který není obyčejným RS na sem tam nějaký článek, ale umožnuje obsluhu závažnejších věcí a situací a proto jsem se musel uchýlit k automatickému připojování souborů a k dalším automatizacím, kvůli kterým vznikly tyto nedořešené chybky.

Ještě jednou se omlouvám a předem děkuji za případnou odpověď.
CZechBoY
Profil
pokud jsou cesty správně tak není možné aby to nešlo
zkontroluj to znova - vypiš si úplně cesty
Ugo
Profil
jestli dobre chapu, tak ... problem je v tom, ze include vicemene nenacte soubor tam kde je, ale proste "na konec skriptu" ...
kdyz v soubor.php bude
$x="y";
fce load() {
 include("soubor.php");
 echo $x; // tady by nemelo bejt dostupny
}
echo $x; // normalne vypise y

.. to same v class samozrejme, myslim ze kdyby v soubor.php bylo global $x; tak se nic nezmeni, jediny reseni co me napada je v ty funkci projit GLOBALS a z kazdy si udelat globalni promenou v ty funkci
foreach($GLOBALS as $key=>$val) {
 global $$key;
}

nemam to odzkousene a nejsme si jist an vic nez 90% :) nejlepsi bys mel pouzivat misto promenejch jednu promenou jako pole a pak si dat jeden global

Moderátor Majkl578: Vkládej prosím kódy mezi značky [pre] a [/pre] (stačí kliknout na ).
Tori
Profil
valecekm:
No a musíte mít ty requires ve funkci? Kdybyste kód pro includování souborů vůbec nezabaloval do funkce, tak se vám includované proměnné i funkce načtou jako globální. Aspoň tak jsem pochopila Alphardovu větu „Spíš bych šel cestou nějakého init.php souboru, který by se jednoduše includoval v každém (hlavním) scriptu“. Přijde mi to v téhle situaci lepší, než to řešit přes $GLOBALS apod.
edit: Upravena formulace.

Ugo:
problem je v tom, ze include vicemene nenacte soubor tam kde je, ale proste "na konec skriptu"
Ne. Viz manuál: „If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function.“
Ugo
Profil
jeste dodatek ... taky mi to obecne prijde jako chyba v navrhu, otazkou je proc. obcas je treba ustoupit prasarne aby byla dobra syntaxe vysl. systemu, ale vic nez nad tim jak udelat tohle se zamysli nad tim, jak to udelat uplne jinak pripadne napis presne co delas ... ono uz bylo vymysleno vsechno. jinak k tem globals (fakt bych to nedoporucil i kdyby to byla jedina moznost - coz nevim) , muzes si udelat pole z globals pred requirem, udelat rozdil s polem po req. a pak projit jenom ty co sou novy (asi byly v souboru) :D ... a nebo si rovnou udelej vsema FW znamou funkci slow() {sleep(5)} :)
CZechBoY
Profil
proměnné v includovaných souborech jsou dostupné ze švech souborů (skriptů)...
php1.php:
<?php
$pozdrav="ahoj";
?>

php2.php:
<?php
echo $pozdrav;
?>

toto bude fungovat
valecekm
Profil
Ugo:
Vyzkouším a uvidím. ;-).
Tori:
Děkuji za nakopnutí na manuál, jaksi se mi zatemnilo, když v tom sedím :-)..jinak k Vašemu prvnímu:
Jak jsem napsal výše, ustoupil jsem od toho, ovšem teď jsem se musel uchýlit k fci, protože tam mohu předat parametry z jaké složky se mají soubory načítat(složek je v systému více a každá obsahuje něco jiného) a podle toho co chci připojit, tak to připojuji buď z té složky a nebo z té a pak si navíc můžu předat jestli chci připojit jen jeden určitej soubor a nebo naopak že z celé složky nechci soubor nějakej jinej, který by mi házel v dané situaci chybu...velmi težce by se mi v celém systému někde definovalo co chci a co nechci a z kamo chci a možná by nastali ještě větší konflikty než nastaly teď a chápu, že když si programátor ručně připojí jednotlivé skripty, tak ví přesně kde co je a tak, ale při změně je to otrocké přepisování....Řekněme, že je to nějaký systém s mnoha zařízenímy a tyto zařízení mají více částí a některé jsou společné jiné jsou individuální, takže si dokážete představit co by se dělo, když bych provedl nějakou změnu(přidal nějakou funkční část) a kvůli tomu musel přepisovat 170 souborů abych ji připojil do všech...podotýkám jen při přidání jedné části. V tomto systému jsou hlášeny poruchy daných zařízení, má nad nimi dohled servis a poté i samotní zákazníci. Otázka proč to neudělat includnutím 1 souboru, který bude mít všechny ostatní soubory includnuté v sobě?, protože se mi pak budou jen težce definovat soubory, které chci a které ne....Proto jsem se musel uchýlik k prasárně, no prasárně, ono je to přeci jen programovej kód a do spousty aplikací člověk ani nevidí, takže je nemůže posoudit a má o daném programu představu že je výborný..Ano proč ne, výborný být může, ale je potom vůbec opodstatněné jak je napsaný?
Ugo
Profil
Tori:
diky za navedeni, ted jak tak premejslym tak sem si to vyvodil z jednoho prikladu, kterej ale funguje tak jak je popsano a jak rikas, takze fatal error v dedukci :)
Tori
Profil
valecekm:
a nebo naopak že z celé složky nechci soubor nějakej jinej, který by mi házel v dané situaci chybu
Jakou? Provede se nežádoucí akce, konfliktní názvy funkcí / proměnných, ...?

Špatně jsem to pochopila, myslela jsem, že vždy se includují všechny soubory.
Co jsou zač ty proměnné, které si skripty předávají - můžete některé spolu s funkcemi logicky spojit do objektů? Tohle: „je to nějaký systém s mnoha zařízenímy a tyto zařízení mají více částí a některé jsou společné jiné jsou individuální“ vypadá jako kandidát na abstraktní třídu + několik odvozených. Pak už by těch proměnných nesouvisejících s objekty snad zbylo málo, takže by šly přehledněji ukládat do $GLOBALS['spolecnaData']. Když už používat glob.proměnné, tak radši ať jich je co nejméně, aby to bylo ještě udržovatelné (můj subj.názor).
Anebo šlo by rozdělit includované funkce do logických skupin tak, aby vždy byla potřeba buď celá skupina nebo nic (a pak volat třeba nactiFunkce(array('uzivatelske', 'servis', 'zarizeniXYZ'));)? Tím byste v případě přidání nové funkčnosti skupině jen dopsal soubor do pole v nactiFunkce(), na jednom místě. To jen tak co mě teď k tomu napadlo, neberte to jako nějaké best practice nebo co. :)
Crusher
Profil
valecekm:
Asi vim co by ti mohlo pomoci. Mam jedno podobne reseni, nerikam ze je korektni s dnesni verzi PHP (uz "objektovou"), ale v tom co bys chtel by ti to melo pomoci.
OK ...

Vytvor si jeden php soubor (pojmenujme jej treba "load_souboru.php"), ktery bude obsahovat pouze "pruchod" tvou funkci (nebude obsahovat funkci, jen jeji obsah). Tento soubor nasledne muzes nacist kdekoli v systemu budes chtit (je to jako volani funkce, jen se nebude jednat o funkci).

Nazorne nize:

<?php

// !!! testy jestli jsou deklarovane "vstupni" promenne uz necham na tobe  (klasicky to asi cele zabal jen do IFu) !!!

$slozka = dir($cesta); 

// pole podporovanych pripon souboru
$pole_pripon=array('php','inc','PHP','INC');
$pole_souboru = array(); // vytvori zatim prazdne pole pro soubory

//// NACTENI SOUBORU A ULOZENI DO POLE ////
//----------------------------------------------------------

while($soubor=$slozka->read()) /* precte soubory ve slozce */{
  if ($soubor=="." || $soubor=="..") continue; // vylouci stejny a nadrazeny adresar 
$soubor_n = explode(".",  $soubor); // rozdeli priponu a nazev souboru do pole
$pripona = $soubor_n[1]; // pripona souboru
    foreach($pole_pripon as $pripona_z) // prohledani pole pripon
    {
// kontrola souboru jestli je soubor povoleny soubor pro vlozeni (podle pripony)
if ($pripona==$pripona_z){$pole_souboru[] = $cesta."/".$soubor;} // ulozi sb. do pole    
  }
 } 

sort($pole_souboru); // seradi prvky v poli pole nazvu(cisla na zacatku)
$prvku_v_poli = count($pole_souboru)-1; // pocet prvku v poli

//// POKUS O PRIPOJENI SOUBORU ////
//----------------------------------------------

for ($i=0; $i<=$prvku_v_poli; $i++) {
    ${'req_i'.$i} = $pole_souboru[$i];
    require ${'req_i'.$i};/*echo '$req_i'."$i";}*/
 }
?>


No a nakonec muzes kdekoli v systemu zavolat jednoduchy kousek kodu:

$cesta = "require_file"; // cesta k souborum kterou zrovna ted potrebujes, menit muzes podle potreby
require "load_souboru.php";
unset($cesta); // to jen aby se pripadne nezachovalo pri dalsim "volani" a testovani


Mozna to neni elegantni jako funkce a asi to neni ani moc "objektove", ale myslim, ze by to melo tvuj problem vyresit.
:-)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0