Помогни ни да направим Uroci.net по - богат! Добави урок

Референции в PHP

PHP » PHP
thelordofweb   трудност:    видян: 6863

Много спорове за референциите в PHP започват с „референциите са объркващи”. Всъщност , референциите са много елементарна концепция за схващане.

Референциите в PHP са средство за достигане до съдържанието на променлива чрез различни имена. Тези имена ще са псевдоними на базовата променлива и ще сочат към нея. Освен това те могат да бъдат използвани за по-кратко записване на имена на променливи. Така те ще бъдат достъпни по-удобно и по-практично до съдържанието на техните базови променливи, ако имената на базовите променливи е дълго и сложно.

Тези разработчици , които са запознати с езици за програмиране, като C++ или Java ще забележат, че референциите в PHP не са аналогични с указателите.

Всички имена на променливи в PHP са автоматично свързани със стойности в паметта. Използвайки референции, ние може да свържем две имена на променлива към същата стойност в паметта. Трябва да знаем , че име на променлива и съдържание на променлива са две различни неща.

За да разберем как работят референциите трябва да знаем първо как PHP работи с променливите, които не са достъпни като референции, а по стойност.

Взимане на стойност от друга променлива

Пример 1 :

<?php

$a = 1;

$b = $a;

$b++;

еcho $a; // ще изведе 1

еcho $b; // ще изведе 2

?>

Предаване на стойност като аргумент на функция

Пример 2 :

<?php

function addFive( $num ) {

$num += 5;

}

$original_num = 10;

addFive( $original_num);

print( $original_num); // Ще изведе 10

?>

Предаване на стойност като аргумент на метод от обект

Пример 3 :

<?php

class DefensiveAttack {

/**

* My IP address

*

* @access protected

* @var string

*/

var $mMyIpAddress = '127.0.0.1';

/**

* Set my IP address

*

* @access public

* @param string $ip

*/

function SetMyIpAddress($ip) {

$this->mMyIpAddress = $ip;

}

/**

* Clear my ip

*

* @access public

*/

function ClearMyIP() {

$this->mMyIpAddress = '';

}

}

$my_ip = '212.116.142.*';

$object = new DefensiveAttack();

$object->SetMyIpAddress($my_ip);

echo $object->mMyIpAddress;// Ще изведе 212.116.142.*

echo $my_ip;// Ще изведе 212.116.142.*

$object->ClearMyIP(); //Изтриваме съдържанието на $mMyIpAddress

echo $object->mMyIpAddress;// Няма да изведе нищо

echo $my_ip;// Ще изведе 212.116.142.*

?>

Сега започнем да разглеждаме предаването на стойности като референция.

Достъп до стойност на друга променлива като референция към нея.

Пример 1:

<?php

$a = 1;

$b = &$a;

$b++;

еcho $a; // ще изведе 2. При увеличаването на стойността на $b променяме стойността на $a

еcho $b; // ще изведе 2

?>

Пример 2:

<?php

$A=array('a' => 'aaa', 'b' => 'bbb');

$b=&$A['b']; // $b сочи към елемент “b” от масив $A

$b=0; // $A['b']=0;

echo $A['b']; // изкарва на екрана 0

?>

За да се създаде референция , не е нужно да съществува стойност към която да сочи.

<?php

$A=array('a' => 'aaa', 'b' => 'bbb');

$b=&$A['c']; // $b сочи към 'c' индекса на масива $A

// Сега масива $A съдържа ‘c’ индекс, но той е празен.

echo " Съдържанието на 'c' индекса от масива $A : (".$A['c'].")";

?>

Когато дадена променлива съдържа име на друга променлива, това се нарича символна референция.

Пример 3:

<?php

$a=10;

$b=20;

$c=30;

$p="a"; // съдържа името на друга променлива (в случая на ‘a’)

echo $$p; // това е референция към $a и ще изведе 10

$$p=100; // тука задаваме стойност не на $p, а на $a. Задаваме 100.

echo $a; // ще изведе 100 вместо 10

?>

Предаване на аргумент като референция към функция

Пример1 :

<?php

function addFive( &$num ) {

// Увеличаваме $original_num с 5

$num += 5;

}

$original_num = 10;

// Увеличаваме $original_num с 5

addFive( $original_num );

// $original_num е вече 15

print( $original_num );

?>

Връщане на референция от функция

<?php

//Връща референция

function &addFive( &$num ) {

$num+=5;

return $num;

}

$original_num = 10;

//референция , която сочи към върнатата стойност от addFive

$returned_num = & addFive( $original_num );

//Променяме $original_num и в същото време променяме върнатата стойност от addFive.

//В този случай $returned_num

$original_num += 10;

print( $returned_num ); // показва на екрана 25

?>

 

 

Предаване на референция като аргумент на метод от обект

Тука това е почти същото, както при предаването на референция като аргумент или връщане на референция при функциите.

Пример :

<?php

class DefensiveAttack {

/**

* My IP address

*

* @access protected

* @var string

*/

var $mMyIpAddress = '127.0.0.1';

/**

* Set my IP address by reference

*

* @access public

* @param string $ip

*/

function SetMyIpAddress(&$rIp) {

$this->mMyIpAddress = &$rIp;

}

/**

* Clear my ip

*

* @access public

*/

function ClearMyIP() {

$this->mMyIpAddress = '';

}

/**

* Get My IP

*

* @access public

*/

function &GetIp() {

return $this->mMyIpAddress;

}

}

$my_ip = '212.116.142.*';

$object = new DefensiveAttack();

//Предаваме променлива като референция

$object->SetMyIpAddress($my_ip);

//Връща референция към mMyIpAddress, която сочи към $my_ip

$i_will_get_ip =& $object->GetIp();

echo ('Съдържанието на $i_will_get_ip:') . $i_will_get_ip . '<br />';// Ще изведе 212.116.142.*

echo ('Съдържанието на $object->mMyIpAddress:') . $object->mMyIpAddress . '<br />';// Ще изведе 212.116.142.*

echo ('Съдържанието на $my_ip:') . $my_ip . '<br />';// Ще изведе 212.116.142.*

$object->ClearMyIP(); //Изтриваме съдържанието на $mMyIpAddress

echo ('Съдържанието на $object->mMyIpAddress след $object->ClearMyIP():') . $object->mMyIpAddress . '<br />';// Няма да изведе нищо

echo ('Съдържанието на $my_ip след $object->ClearMyIP():') . $my_ip . '<br />';// Няма да изведе нищо

echo ('Съдържанието на $i_will_get_ip след $object->ClearMyIP():') . $i_will_get_ip . '<br />';// // Няма да изведе нищо

?>

Особености при обектите в PHP5

В PHP5 обектите се предават като референция. За да направите две различни инстанции на даден обект е нужно да го клонирате . В противен случай , при промяна на инстанцията от обекта вие ще променяте базовия обект. Това става много лесно.

Пример:

$object = new DefensiveAttack();

$object->mMyIpAddress = '212.116.142.*';

echo ('Съдържанието на $object->mMyIpAddress:') . $object->mMyIpAddress . '<br />';// Ще изведе 212.116.142.*

//Предава се чрез референция

$object1 = $object;

//Променяме $object->mMyIpAddress

$object1->mMyIpAddress = '127.0.0.1';

echo ('Съдържанието на $object->mMyIpAddress:') . $object->mMyIpAddress . '<br />';// Ще изведе 127.0.0.1

echo ('Съдържанието на $object1->mMyIpAddress:') . $object1->mMyIpAddress . '<br />';// Ще изведе 127.0.0.1

Клонирането става със запазената дума на PHP “clone”

Пример :

$object = new DefensiveAttack();

$object->mMyIpAddress = '212.116.142.*';

echo ('Съдържанието на $object->mMyIpAddress:') . $object->mMyIpAddress . '<br />';// Ще изведе 212.116.142.*

//Клонираме обекта

$object1 = clone $object;

//Не променяме $object->mMyIpAddress, а само $object1->mMyIpAddress

$object1->mMyIpAddress = '127.0.0.1';

echo ('Съдържанието на $object->mMyIpAddress:') . $object->mMyIpAddress . '<br />';// Ще изведе 127.0.0.1

echo ('Съдържанието на $object1->mMyIpAddress:') . $object1->mMyIpAddress . '<br />';// Ще изведе 212.116.142.*

Референцията като удобство

Споменах , че също така референциите може да се използват и за удобство, като заменим именуваните вече с дълги имена на променливи с техни по-къси псевдоними.

Пример :

<?php

// Създаваме масив от стойности

$arrNamesThatAreFairlyCommon = Array("Joe", "Bob", "Sarah", "Bill", "Suzy");

// Показваме съдържанието на масива

print_r($arrNamesThatAreFairlyCommon);

// Референция към $arrNamesThatAreFairlyCommon

$arrNames =& $arrNamesThatAreFairlyCommon;

// Показваме съдържанието на масива достъпен от $arrNames

print_r($arrNames);

?>

Премахване на променлива

Какво става когато се премахне променливата съдържаща референция, която сочи към някакви данни?

Ако унищожим такава променлива ще прекъснем единствено връзката към данните, а те си остават.

Пример :

<?php

$a = 1;

$b =& $a;

unset($a);

print $b;

?>

Добри и лоши практики

Понякога , когато използваме референции, кода може да стане много объркан, труден за четене и разбиране.

Пример 1 - Лоша практика:

<?php

function msg($message) {

echo $message;

}

$my_message = 'Hello World!';

// Задаването на аргумент като референция по този начин е лоша практика и може да ни обърка

msg(&$my_message);

?>

Предвидена е една директива в конфигурационния файл на PHP „allow_call_time_pass_reference = Off” за да ни пази от такъв вид програмиране. По подразбиране стойността и е Off .

Пример 2 - Добра практика:

<?php

// Приемането на референция от функцията е добра практика

function msg(&$message)

{

echo $message;

}

$my_message = 'Hello World!';

msg($my_message);

?>

Кога да използваме референции и кога не?

В зависимост от приложението , вие трябва внимателно да прецените кога и къде да използвате референции. Примерно , когато желаете да спестите ненужно изразходване на памет и увеличите бързодействието на приложението си. Това става тогава, когато вместо да копирате една променлива(масиви,...) в друга, вие само задавате референция , която сочи към базовата променлива. Има смисъл да се използват за големи по обем данни(масиви, обекти,..) , но не е нужно да се употребяват референциите за нищожни данни. Примерно:

$a = ‘Няма бира!’;

$b = $a; // Няма нужда от $b =& $a;

При това положение няма да се усети положителен ефект, а само ще обърка кода.


Автор: Тодор Илиев



Регистрирайте се, за да добавите коментар


Калдейта ЕООД - © 2003-2010. Всички права запазени.
Препоръчваме: Национален Бизнес | Bomba.bg | IT Новини | Диплома.бг | TRAVEL туризъм | Реферати | AmAm.bg | Иде.ли | Курсови работи | Фото Форум | Spodeli.net | Фото-Култ | Atol.bg | Elmaz.com | MobileBulgaria.com | Казанлък.Com