Dodatok E . Rozšírenie PHP

Obsah
Pridávanie funkcií do PHP
Volanie užívateľských funkcií
Hlásenie chýb

Pridávanie funkcií do PHP

Použitie funkčných argumentov

Typ každého argumentu sa ukladá do typového poľa pval . Tento typ môže byť jedno z následujúceho :

Tabuľka E-1 . Interné typy PHP

Reťazec
Pohyblivá čiarka s dvojitou presnosťou
Dlhý integer
Pole
Nič
? ? ( ak niektoré z týchto nemôže prejsť na funkciu - delete )


Ak dostanete argument jedného typu a chceli by ste ho použiť ako iný alebo ak chcete prinútiť argument , aby bol príslušnéhé typu , môžete použiť následujúce konverzné funkcie :

 
convert_to_long(

 
arg1)

 
;

 
convert_to_double(arg1)

 
;

 
convert_to_string(arg1)

 
;

 
convert_to_boolean_long(arg1)

 
;

 
/

 
*

 
Ak

 
je

 
reťazec

 
"

 
"

 
alebo

 
"0"

 
,

 
bude

 
0

 
,

 
inak

 
1

 
*

 
/

 
convert_string_to_number(arg1)

 
;

 
/

 
*

 
Konvertuje

 
reťazec

 
buď

 
na

 
LONG

 
alebo

 
DOUBLE

 
závisiac

 
na

 
reťazci

 
*

 
/





Tieto funkcie robia konverziu na mieste . Nevracajú nič .

Aktuálny argument je uložený v zväzku ; členmi :



Manažment pamäte vo funkciách

Každá pamäť , ktorú funkcia potrebuje by sa mala vyhradiť buď s emalloc( ) alebo estrdup( ) . Toto abstraktné funkcie manipulujúce s pamäťou , ktoré vyzerajú ako normálne funkcie malloc( ) a strdup( ) . Pamäť by sa mala uvoľniť s efree( ) .

V tomto programe dva druhy pamätí : pamäť , ktorá je vrátená do parsera v premennej a pamäť , ktorú potrebujete pre dočasné uloženie vo vašej internej funkcii . Keď priraďujete reťazec k premennej , ktorá sa vracia do parsera , musíte sa uistiť , že pamäť najprv vyhradíte buď s emalloc( ) alebo estrdup( ) . Túto pamäť by ste NIKDY nemali uvoľniť vy , pokiaľ neskôr v tej istej funkcii neprepíšete svoje pôvodné priradenie ( avšak tento typ programovacej techiky nie je dobrý ) .

Pre hocijakú dočasnú / trvalú pamäť , ktorú potrebujete vo svojich funkciách / knižnici , by ste mali použiť tri funkcie emalloc( ) , estrdup( ) a efree( ) . Správajú sa PRESNE ako ich opačné funkcie . Všetko , čo emalloc( )'ujte alebo estrdup()'ujete , musíte na niektorých miestach efree()'ovať , pokiaľ kód do konca neuviazne ; inak pamäť pretečie . Významom " funkcie sa správajú presne ako ich opačné funkcie " je : ak efree()'ujete niečo , čo nebolo emalloc()'ované alebo estrdup() 'ované , môže sa objaviť zlyhanie segmentácie . Takže sa prosím o to postarajte a uvoľnite celú zbytočnú pamäť .

Ak kompilujete s " -DDEBUG" , tak po dokončení špecifického skriptu , PHP vypíše zoznam všetkej pamäte , ktorá bola vyhradená použitím emalloc( ) a estrdup() , ale ktorá nebola nikdy uvoľnená s efree( ) .

Nastavovanie premenných v Tabuľke premenných

Existuje množstvo makier , ktoré uľahčujú nastavenie premennej v tabuľke symbolov :



Varovanie

Buďte opatrný s SET_VAR_STRING . Časť hodnoty musí byť malloc ' ovaná manuálne , pretože kód pamäťového manažmentu sa neskôr pokúsi tento ukazovateľ uvoľniť . Nepresúvajte staticky vyhradenú pamäť do SET_VAR_STRING .

Tabuľky symbolov v PHP implementované ako tabuľky hash . V hocakom danom čase je symbol_table ukazovateľom ' hlavnej ' tabuľky symbolov a active_symbol_table ukazuje na teraz aktívnu tabuľku symbolov (tieto môžu byť identické ako pri štarte , alebo rôzne , ak ste vo vnútri funkcie ) .

Následujúce príklady používajú ' active_symbol_table ' . Mali by ste ju nahradiť s symbol_table , ak chcete špecificky pracovať s ' hlavnou ' tabuľkou symbolov . Rovnako aj rovnaké funkcie sa môžu použiť na polia , ako je vysvetlené nižšie .

Príklad E-3 . Kontrola , či $foo existuje v tabuľke symbolov

 
if

 
(

 
hash_exists(active_symbol_table

 
,"foo",sizeof("foo"))

 
)

 
{

 
existuje..

 
.

 
}

 
else

 
{

 
neexistuje

 
}



Príklad E-4 . Hľadanie veľkosti premennej v tabuľke symbolov




Polia sú v PHP implementované použitím rovnakých hash tabuliek ako tabuliek symbolov. To znamená, že dve uvedené funkcie sa tiež dajú použiť na kontrolu premenných vo vnútri polí.

Ak chcete definovať nové pole v tabuľke symbolov , mali by ste urobiť následujúce .

Najprv by ste mali zistiť , či existuje a vhodne ju zrušiť , a to použitím hash_exists( ) alebo hash_find( ) .

Ďalej , inicializujte pole :

Príklad E-5 . Inicializovanie nového poľa




Tento kód deklaruje nové pole, nazvané $foo, v tabuľke symbolov. Toto pole je prázdne.

Tu je uvedené ako sa do neho pridávajú položky :

Príklad E-6 . Pridávanie položiek do nového poľa

 
pval

 
entry

 
;

 
entry.type

 
=

 
IS_LONG

 
;

 
entry.value.lval

 
=

 
5

 
;

 
/

 
*

 
definuje

 
$foo["bar"

 
]

 
=

 
5

 
*

 
/

 
hash_update(arr.value.ht

 
,"bar",sizeof("bar")

 
,

 
entry,sizeof(pval),NULL)

 
;

 
/

 
*

 
definuje

 
$foo[7

 
]

 
=

 
5

 
*

 
/

 
hash_index_update(arr.value.ht,7

 
,

 
entry,sizeof(pval),NULL)

 
;

 
/

 
*

 
definuje

 
ďalšie

 
voľné

 
miesto

 
v

 
$foo[]

 
,

 
*

 
$foo[8]

 
,

 
aby

 
bol

 
5

 
(pracuje

 
ako

 
php2

 
)

 
*

 
/

 
hash_next_index_insert(arr.value.ht

 
,

 
entry,sizeof(pval),NULL)

 
;



Ak by ste chceli zmeniť hodnotu, ktorú ste vložili do hashu, najprv by ste ju z hashu museli obnoviť. Aby ste sa vyhli prebytku, môžete poskytnúť pval ** do prídavnej funkcie hash a ona sa aktualizuje s pval * adresou vloženého elementu v hashi. Ak je tá hodnota NULL (ako vo všetkých horeuvedených príkladoch) - parameter sa ignoruje.

hash_next_index_insert( ) používa viac-menej istú logiku ako "$foo[ ] = bar ; " v PHP 2.0 .

Ak budujete pole na vrátenie z funkcie , môžete inicializovať pole práve tak ako sa to urobilo vyžšie :

 
if

 
(

 
array_init(return_value

 
)

 
==

 
FAILURE

 
)

 
{

 
zlyhal...

 
;

 
}



...a potom pridaním hodnôt s pomocníkom funkcií :




Samozrejme , ak sa pridanie neurobí hneď po inicializácii poľa , pravdepodobne sa budete musieť najprv postarať o pole :

 
pval

 
*arr

 
;

 
if

 
(hash_find(active_symbol_table

 
,"foo",sizeof("foo")

 
,(void

 
**

 
)

 
arr)==FAILURE

 
)

 
{

 
nemôže

 
nájsť..

 
.

 
}

 
else

 
{

 
použi

 
arr

 
-

 
value.ht..

 
.

 
}





Všimnite si , že hash_find zachytáva ukazovateľ do pval ukazovateľa , a nie pval ukazovateľa .

Vlastne akákoľvek hash funkcia vracia SUCCESS alebo FAILURE ( okrem hash_exists() , ktorá vracia prevdivú hodnotu booleanu ) .

Vrátenie komplexných hodnôt

Vaša funkcia môže tiež vrátiť komplexný dátový typ ako je objekt alebo pole .

Vrátenie objektu :

  1. Zavolajte funkciu object_init( return_value ) .

  2. Doplňte hodnoty . Funkcie slúžiace na tento účel vypísané nižšie

  3. Pípadne , pre tento objekt zaregistrujte funkcie . Aby ste získali hodnoty objektu , funkcia by " ich " mala vybrať z active_symbol_table . Jej typ by mal byť IS_OBJECT , a je to pôvodne platná hash tabuľka ( t.j. , môžete použiť platné hash funkcie na .value.ht ) . Registrácia funkcie sa urobiť použitím :

    
    
    
    




Funkcie používané na obsadenie objektu :

  • add_property_long( return_value , property_name , l ) - Pridá vlastnosť nazvanú 'property_name' , typu long , rovnú 'l '

  • add_property_double( return_value , property_name , d ) - To isté , len pridá double

  • add_property_string( return_value , property_name , str ) - To isté , len pridá reťazec

  • add_property_stringl( return_value , property_name , str , l ) - To isté , len pridá reťazec dĺžky 'l '



Vrátenie poľa :

  1. Zavolajtearray_init( return_value ) .

  2. Doplňte hodnoty . Funkcie slúžiace na tento čel uvedené nižšie .



Funkcie používané na obsadenie poľa :

  • add_assoc_long( return_value,key,l ) - pridá associatívnu položku s kľúčom 'key ' a hodnotou long 'l '

  • add_assoc_stringl( return_value,key,str,length,duplicate ) špecifikuje dĺžku reťazca

  • add_index_long( return_value,index,l ) - pridá položku indexu 'index ' s hodnotou long 'l '

  • add_index_stringl( return_value,index,str,length ) - špecifikuje dĺžku reťazca

  • add_next_index_long( return_value,l ) - pridá položku poľa do ďalšieho voľného offsetu s hodnotou long 'l '

  • add_next_index_stringl( return_value,str,length ) - špecifikuje dĺžku reťazca



Použitie zoznamu zdrojov

PHP štandardný spôsob zaobchádzania s rôznymi typmi zdrojov . Toto nahrádza všetky miestne linkované zoznamy v PHP 2.0 .

Dostupné funkcie :

  • php3_list_insert( ptr , type ) - vracia 'id ' novo vloženého zdroja

  • php3_list_delete( id ) - odstráni zdroj so špecifikovaným id

  • php3_list_find( id,*type ) - vracia ukazovateľ zdroja so špecifikovaným id , aktualizuje 'type ' na typ zdroja

Typicky sa tieto funkcie používajú pre SQL ovládače, ale dajú sa použiť prehocičo iné; na príklad na zachovávanie popisovačov súborov.

Typický zoznam kódu by vyzeral takto :

Príklad E-7 . Pridanie nového zdroja

 
RESOURCE

 
*resource

 
;

 
/

 
*

 
...vyhradí

 
pamäť

 
pre

 
zdroj

 
a

 
získa

 
zdroj..

 
.

 
*

 
/

 
/

 
*

 
pridá

 
nový

 
zdroj

 
do

 
zoznamu

 
*

 
/

 
return_value

 
-

 
value.lval

 
=

 
php3_list_insert((void

 
*

 
)

 
resource

 
,

 
LE_RESOURCE_TYPE)

 
;

 
return_value

 
-

 
type

 
=

 
IS_LONG

 
;



Príklad E-8 . Použitie existjúceho zdroja

 
pval

 
*resource_id

 
;

 
RESOURCE

 
*resource

 
;

 
int

 
type

 
;

 
convert_to_long(resource_id)

 
;

 
resource

 
=

 
php3_list_find(resource_id

 
-

 
value.lval

 
,

 
type)

 
;

 
if

 
(type

 
!=

 
LE_RESOURCE_TYPE

 
)

 
{

 
php3_error(E_WARNING

 
,

 
"

 
index

 
%d

 
zdroja

 


 
nesprávny

 
typ",resource_id

 
-

 
value.lval)

 
;

 
RETURN_FALSE

 
;

 
}

 
/

 
*

 
...použi

 
zdroj..

 
.

 
*

 
/



Príklad E-9 . Odstránenei existujúceho zdroja




Typy zdroja by mali byť registrované v php3_list.h, v list_entry_type. Okrem toho, ku kažkému definovanému typu zdroja by sa mal pridať kód vypnutia, v list_entry_destructor() v súbore list.c (dokonca aj keď nemáte čo urobiť pri vypnutí, musíte pridať prázdny prípad).

Použitie trvalej tabuľky zdroja

PHP štandardný spôsob ukladania trvalých zdrojov ( t.j , zdroje , ktoré sa uchovávajú medzi zásahmi ) . Prvý modul , ktorý mal používať túto vlastnosť bol modul MySQL , a následne mSQL , takže pri čítaní mysql.c môžete nadobudnúť dojem , aký trvalý zdroj by sa mal použiť . Funkcie , na ktoré by ste sa mali pozrieť :



Všeobecný význam trvalých modulov je tento :

  1. Nakódujete celý svoj modul tak , aby pracoval so zoznamom platných zdrojov , ako bolo spomenuté v skecii ( 9 ) .

  2. Nakódujte extra prepojenia na funkcie , ktoré zistia , či zdroj existuje v zozname trvalých zdrojov . Ak áno , zaregistrujte ho tak ako v zozname platných zdrojov ako ukazovateľ na zoznam trvalých zdrojov ( pretože zvyšok kódu by mal pracovať okamžite ) . Ak nie , tak ho vytvorte , pridajte ho do zoznamu trvalých zdrojov A pridajte naň ukazovateľ zo zoznamu platných zdrojov , takže by celý kód fungoval , pretože je v zozname platných zdrojov , ale na druhom prepojení by sa zdroj našiel v zozname trvalých zdrojov a používal by sa bez potreby znovuobnovenia . Tieto zdroje by ste mali zaregistrovať ako rozličné typy ( t.j . LE_MYSQL_LINK pre netrvalý odkaz a LE_MYSQL_PLINK pre trvalý odkaz ) .



Ak si prečítate mysql.c , zistíte , že okrem komplexnejších funkcií spojenia , sa nič , čo zostalo v module , nesmie zmeniť .

Úplne také isté rozhranie existuje pre zoznam platných zdrojov a zoznam trvalých zdrojov , iba ' list ' sa nahradil s 'plist ' :

  • php3_plist_insert( ptr , type ) - vracia 'id ' novo vloženého zdroja

  • php3_plist_delete( id ) - odstraňuje zdroj so špecifickým id

  • php3_plist_find( id,*type ) - vracia ukazovateľ zdroja so špecifickým id , aktualizuje 'type ' na typ zdroja

Ale je viac ako pravdepodobné , že tieto funkcie by sa pre vas preukázali ako zbytočné , keď by ste sa pokúšali implementovať trvalý modul . Niekto by typicky chcel použiť fakt , že zoznam trvalých zdrojov je v skutočnosti hash tabuľka . Na príklad , v moduloch MySQL / mSQL , keď sa volá pconnect( ) (trvalé prepojenie) , funkcia vybuduje reťazce z host / user / passwd , ktoré sa funkcii predali , a hashuje SQL odkaz s týmto reťazcom ako kľúč . Ďalej , niekto zavolá pconnect( ) s rovnakým host / user / passwd , vygeneruje sa rovnaký kľúč a funkcia vyhľadá SQL odkaz v trvalom zozname .

Kým sa pozriete na ďalej zdokumentované , mali by ste sa pozrieť na mysql.c alebo msql.c , aby ste videli , ako by sa schopnosti hash tabuľky plistu mali použiť .

Jedna dôležitá poznámka : zdroje , ktoré idú do zoznamu trvalých zdrojov , sa *NESMÚ* vyhradiť s pamäťovým manažérom PHP , t.j. , NEMALI by sa vytvárať s emalloc( ) , estrdup( ) , atď . Radšej by sa mali použiť regulérne malloc( ) , strdup( ) , atď . Dôvod je jednoduchý - na konci požiadavky ( konci zásahu ) , sa každá pamäťová informácia , ktorá bola vyhradená pomocou pamäťového manažéra PHP , vymaže . Nakoľko trvalý zoznam nie je na to , aby sa na konci požiadavky vymazal , manažér pamäte PHP sa nesmie používať na vyhradenie zdrojov , ktoré do neho idú. .

Keď registrujete zdroj , ktorý bude v trvalom zozname , mali by ste k nemu pridať deštruktorov v netrvalom aj v trvalom zozname . Deštruktor by nemal v netrvalom zozname deštruktora urobiť nič . Ten v trvalom zozname deštruktora by mal vhodne uvoľniť akékoľvek zdroje získané tým typom ( t.j . pamäť , SQL odkazy , atď ) . Práve tak ako s netrvalými zdrojmi , *MUSÍTE* ku každému zdroju pridať deštruktora , aj keď nevyžaduje žiaden a keby bol aj prázdny . Pamätajte , nakoľko emalloc( ) a 'priatelia ' nemajú byť použité spoločne s trvalým zoznamom , ani tu nesmiete použiť efree( ) .