क्या PHP वैरिएबल मूल्य या संदर्भ द्वारा पारित किए जाते हैं?
क्या PHP वैरिएबल मूल्य या संदर्भ द्वारा पारित किए जाते हैं?
जवाबों:
यह PHP प्रलेखन के अनुसार मूल्य के अनुसार है ।
डिफ़ॉल्ट रूप से, फ़ंक्शन तर्क मान द्वारा पारित किए जाते हैं (ताकि यदि फ़ंक्शन के भीतर तर्क का मान बदल जाए, तो यह फ़ंक्शन के बाहर नहीं बदला जाता है)। किसी फ़ंक्शन को अपने तर्कों को संशोधित करने की अनुमति देने के लिए, उन्हें संदर्भ द्वारा पारित किया जाना चाहिए।
किसी फ़ंक्शन के लिए तर्क को हमेशा संदर्भ से पारित किया जाता है, फ़ंक्शन परिभाषा में एक ampersand ( & ) को तर्क नाम के लिए प्रस्तुत करता है।
<?php
function add_some_extra(&$string)
{
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
?>
$str = add_some_extra($str);
जैसे मैं संदर्भ का उपयोग नहीं कर रहा था, है ना? फिर उस का वास्तविक जोड़ा मूल्य क्या है?
$str
आपके मामले में, इसे रिक्त रखा जाएगा।
PHP में, डिफ़ॉल्ट रूप से ऑब्जेक्ट्स को एक नई ऑब्जेक्ट के संदर्भ कॉपी के रूप में पारित किया जाता है।
इसका उदाहरण देखें …………।
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj->abc = 30;
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 30
अब ये देखिये …………।
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue($obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 10 not 20 same as java does.
अब ये देखिये …………।
class X {
var $abc = 10;
}
class Y {
var $abc = 20;
function changeValue(&$obj)
{
$obj = new Y();
}
}
$x = new X();
$y = new Y();
echo $x->abc; //outputs 10
$y->changeValue($x);
echo $x->abc; //outputs 20 not possible in java.
मुझे आशा है कि आप इसे समझ सकते हैं।
$y
जरूरत नहीं है - इसमें ऐसा कुछ भी नहीं है function changeValue
जिसके लिए अंदर होना जरूरी है class Y
, ताकि दो असंबंधित अवधारणाओं को एक साथ जोड़ दिया जाए। मैं function changeValue
ऊपर की ओर, बाहरी दायरे में जाता हूँ $x = new X();
। सभी संदर्भ निकालें $y
। अब यह देखना आसान है कि पहले दो उदाहरण $ x अकेले छोड़ देते हैं, और तीसरा एक अपनी सामग्री बदलता है new Y()
। यह देखना आसान होगा कि क्या आपने इस तथ्य type
को धराशायी कर दिया है $x
- यह तथ्य कि एक क्षेत्र को शामिल करने के लिए दोनों ही होते हैं X
और यह प्रदर्शित करने के लिए भी अप्रासंगिक हैY
$abc
ऐसा लगता है कि बहुत से लोग भ्रमित हो जाते हैं जिस तरह से वस्तुओं को कार्यों के लिए पारित किया जाता है और संदर्भ साधनों से गुजरता है। ऑब्जेक्ट चर अभी भी मूल्य द्वारा पारित किए जाते हैं, इसका सिर्फ एक मूल्य जो PHP5 में पारित किया गया है वह एक संदर्भ संभाल है। सबूत के रूप में:
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
आउटपुट:
a, b
करने के लिए संदर्भ द्वारा पारित साधन हम चर कॉल करने वाले को देखा जाता है संशोधित कर सकते हैं। जो स्पष्ट रूप से ऊपर कोड नहीं करता है। हमें स्वैप फ़ंक्शन को इसमें बदलना होगा:
<?php
function swap(&$x, &$y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
आउटपुट:
b, a
संदर्भ से पारित करने के लिए।
swap
फ़ंक्शन में चला गया था ; दूसरे शब्दों में, अगर वस्तुओं को "मूल्य से पारित किया गया था"। दूसरी ओर, यह भी ठीक है कि आप क्या अपेक्षा करेंगे यदि कोई ऑब्जेक्ट हैंडल फ़ंक्शन को दिया गया था, जो वास्तव में होता है। आपका कोड इन दो मामलों के बीच अंतर नहीं करता है।
http://www.php.net/manual/en/migration5.oop.php
PHP 5 में एक नया ऑब्जेक्ट मॉडल है। बेहतर प्रदर्शन और अधिक सुविधाओं के लिए PHP की वस्तुओं की हैंडलिंग पूरी तरह से फिर से लिखी गई है। PHP के पिछले संस्करणों में, वस्तुओं को आदिम प्रकार (उदाहरण के लिए पूर्णांक और तार) की तरह संभाला गया था। इस पद्धति का दोष यह था कि जब चर को सौंपा गया था, या किसी विधि के पैरामीटर के रूप में पारित किया गया था, तो शब्दार्थ पूरी वस्तु की प्रतिलिपि बनाई गई थी। नए दृष्टिकोण में, वस्तुओं को हैंडल द्वारा संदर्भित किया जाता है, न कि मूल्य द्वारा (किसी वस्तु के पहचानकर्ता के रूप में हैंडल के बारे में सोच सकते हैं)।
PHP वेरिएबल्स को मान द्वारा असाइन किया गया है, मान द्वारा फ़ंक्शंस को पास किया गया है, और जब ऑब्जेक्ट्स का प्रतिनिधित्व करते / करते हुए संदर्भ द्वारा पारित किए जाते हैं। आप एक का उपयोग करके संदर्भों को पास करने के लिए चर को बाध्य कर सकते हैं
मूल्य / संदर्भ उदाहरण द्वारा असाइन किया गया:
$var1 = "test";
$var2 = $var1;
$var2 = "new test";
$var3 = &$var2;
$var3 = "final test";
print ("var1: $var1, var2: $var2, var3: $var3);
उत्पादन होगा
var1: परीक्षण, var2: अंतिम परीक्षण, var3: अंतिम परीक्षण
मान / संदर्भ परीक्षा द्वारा उत्तीर्ण:
$var1 = "foo";
$var2 = "bar";
changeThem($var1, $var2);
print "var1: $var1, var2: $var2";
function changeThem($var1, &$var2){
$var1 = "FOO";
$var2 = "BAR";
}
उत्पादन होगा:
var1: foo, var2 BAR
संदर्भ परीक्षा द्वारा पास किए गए ऑब्जेक्ट चर:
class Foo{
public $var1;
function __construct(){
$this->var1 = "foo";
}
public function printFoo(){
print $this->var1;
}
}
$foo = new Foo();
changeFoo($foo);
$foo->printFoo();
function changeFoo($foo){
$foo->var1 = "FOO";
}
उत्पादन होगा:
FOO
(यह अंतिम उदाहरण शायद बेहतर हो सकता है ...)
$foo
एक है एक वस्तु को सूचक । फ़ंक्शन के मान से पारित किया$foo
जाता है , क्योंकि इसके पैरामीटर की घोषणा नहीं की गई थी । changeFoo()
changeFoo()
&
आप किसी चर को संदर्भ द्वारा फ़ंक्शन में पास कर सकते हैं। यह फ़ंक्शन मूल चर को संशोधित करने में सक्षम होगा।
आप फ़ंक्शन परिभाषा में संदर्भ द्वारा मार्ग को परिभाषित कर सकते हैं:
<?php
function changeValue(&$var)
{
$var++;
}
$result=5;
changeValue($result);
echo $result; // $result is 6 here
?>
आप इसे किसी भी तरह से कर सकते हैं।
सामने एक 'और' प्रतीक रखो और जो चर तुम पास कर रहे हो वह एक हो जाता है और उसी की उत्पत्ति होती है। यानी: आप इसकी प्रति बनाने के बजाय संदर्भ द्वारा पास कर सकते हैं।
इसलिए
$fred = 5;
$larry = & $fred;
$larry = 8;
echo $fred;//this will output 8, as larry and fred are now the same reference.
PHP5 में आदिम प्रकारों वाले चर मूल्य से पारित किए जाते हैं। ऑब्जेक्ट वाली चर को संदर्भ द्वारा पारित किया जाता है। 2006 से लिनक्स जर्नल का काफी दिलचस्प लेख है जिसमें 4 और 5 के बीच इस और अन्य OO अंतरों का उल्लेख है।
&
।
PHP 5 में संदर्भ द्वारा और PHP में मूल्य द्वारा ऑब्जेक्ट्स पारित किए जाते हैं। चर डिफ़ॉल्ट रूप से मूल्य द्वारा पारित किए जाते हैं!
यहां पढ़ें: http://www.webeks.net/programming/php/ampersand-operator-used-for-assigning-reference.html
&
।
&
को परिभाषा में मापदंडों के सामने परिभाषित नहीं होने पर भी फ़ंक्शन द्वारा संशोधित किया जा सकता है - यदि उन्हें उस मान से पास किया गया है जो उस दायरे में निहित वस्तु है जो फ़ंक्शन को पैरामीटर के रूप में कहा जाता है प्रभावित नहीं होना।
class Holder
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
public function getValue()
{
return $this->value;
}
public function setValue( $value )
{
return $this->value = $value;
}
}
class Swap
{
public function SwapObjects( Holder $x, Holder $y )
{
$tmp = $x;
$x = $y;
$y = $tmp;
}
public function SwapValues( Holder $x, Holder $y )
{
$tmp = $x->getValue();
$x->setValue($y->getValue());
$y->setValue($tmp);
}
}
$a1 = new Holder('a');
$b1 = new Holder('b');
$a2 = new Holder('a');
$b2 = new Holder('b');
Swap::SwapValues($a1, $b1);
Swap::SwapObjects($a2, $b2);
echo 'SwapValues: ' . $a2->getValue() . ", " . $b2->getValue() . "<br>";
echo 'SwapObjects: ' . $a1->getValue() . ", " . $b1->getValue() . "<br>";
विशेषताएँ अभी भी परिवर्तनीय हैं जब संदर्भ से गुजरे नहीं तो सावधान रहें।
आउटपुट:
SwapObjects: b, a SwapValues: ए, बी
जो कोई भी भविष्य में इस पार आता है, मैं इस रत्न को PHP डॉक्स से साझा करना चाहता हूं , जो एक गुमनाम उपयोगकर्ता द्वारा पोस्ट किया गया है :
यहां कुछ भ्रम होने लगता है। संकेत और संदर्भों के बीच का अंतर विशेष रूप से सहायक नहीं है। पहले से ही पोस्ट किए गए कुछ "व्यापक" उदाहरणों में व्यवहार को सरल शब्दों में स्पष्ट किया जा सकता है। उदाहरण के लिए, हेले का कोड वास्तव में वही कर रहा है जिसकी आपको अपेक्षा करनी चाहिए। (उपयोग> = 5.3)
पहला सिद्धांत: एक पॉइंटर एक ऑब्जेक्ट को एक्सेस करने के लिए मेमोरी एड्रेस को स्टोर करता है। किसी भी समय एक वस्तु सौंपी जाती है, एक सूचक उत्पन्न होता है। (मैंने TOO को अभी तक Zend इंजन में गहराई से नहीं उतारा है, लेकिन जहाँ तक मैं देख सकता हूँ, यह लागू होता है)
दूसरा सिद्धांत, और सबसे अधिक भ्रम का स्रोत: किसी फ़ंक्शन को एक चर पास करना डिफ़ॉल्ट रूप से मान पास के रूप में किया जाता है, अर्थात, आप एक प्रतिलिपि के साथ काम कर रहे हैं। "लेकिन वस्तुओं को संदर्भ से पारित किया जाता है!" यहाँ और जावा दुनिया में एक आम गलत धारणा। मैंने कभी WHAT की कॉपी नहीं कहा। डिफ़ॉल्ट पासिंग वैल्यू द्वारा किया जाता है। हमेशा। हालांकि, कॉपी और पास किया जा रहा है, लेकिन सूचक है। "->" का उपयोग करते समय, आप निश्चित रूप से कॉलर फ़ंक्शन में मूल वैरिएबल के समान ही एक्सेस कर रहे होंगे। बस "=" का उपयोग केवल प्रतियों के साथ खेलेंगे।
तीसरा सिद्धांत: "और" स्वचालित रूप से और स्थायी रूप से एक अन्य चर नाम / पॉइंटर को उसी मेमोरी एड्रेस पर सेट करता है जब तक कि आप उन्हें डिकॉउप नहीं करते। यहां "उपनाम" शब्द का उपयोग करना सही है। इसे कूल्हे पर दो बिंदुओं में शामिल होने के रूप में सोचें जब तक कि "अनसेट ()" के साथ जबरन अलग न हो जाए। यह कार्यक्षमता दोनों एक ही दायरे में मौजूद होती है और जब किसी फ़ंक्शन को एक तर्क दिया जाता है। अक्सर पास किए गए तर्क को "मूल्य से गुजरने" और "संदर्भ से गुजरने" के बीच कुछ अंतरों के कारण "संदर्भ" कहा जाता है, जो सी और सी ++ में स्पष्ट थे।
बस याद रखें: वस्तुओं को इंगित करता है, न कि वस्तुओं को स्वयं, कार्यों के लिए पारित किया जाता है। जब तक आप मूल पैरामीटर को वास्तव में पारित करने के लिए अपनी "" सूची में उपयोग नहीं करते हैं, तब तक ये संकेत मूल के कॉपीराइट हैं। जब आप किसी वस्तु के आंतरिक भाग में खुदाई करते हैं, तो मूल परिवर्तन होंगे।
और यहाँ उदाहरण वे प्रदान करते हैं:
<?php
//The two are meant to be the same
$a = "Clark Kent"; //a==Clark Kent
$b = &$a; //The two will now share the same fate.
$b="Superman"; // $a=="Superman" too.
echo $a;
echo $a="Clark Kent"; // $b=="Clark Kent" too.
unset($b); // $b divorced from $a
$b="Bizarro";
echo $a; // $a=="Clark Kent" still, since $b is a free agent pointer now.
//The two are NOT meant to be the same.
$c="King";
$d="Pretender to the Throne";
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByValue($c, $d);
echo $c."\n"; // $c=="King"
echo $d."\n"; // $d=="Pretender to the Throne"
swapByRef($c, $d);
echo $c."\n"; // $c=="Pretender to the Throne"
echo $d."\n"; // $d=="King"
function swapByValue($x, $y){
$temp=$x;
$x=$y;
$y=$temp;
//All this beautiful work will disappear
//because it was done on COPIES of pointers.
//The originals pointers still point as they did.
}
function swapByRef(&$x, &$y){
$temp=$x;
$x=$y;
$y=$temp;
//Note the parameter list: now we switched 'em REAL good.
}
?>
मैंने जावास्क्रिप्ट के लिए इस विषय पर एक व्यापक, विस्तृत ब्लॉग पोस्ट लिखा है , लेकिन मेरा मानना है कि यह PHP, C ++, और किसी भी अन्य भाषा में समान रूप से लागू होता है जहां लोग संदर्भ के माध्यम से मूल्य बनाम पास से भ्रमित होने लगते हैं।
स्पष्ट रूप से, PHP, C ++ की तरह, एक भाषा है जो संदर्भ द्वारा पास का समर्थन करती है। डिफ़ॉल्ट रूप से, वस्तुओं को मूल्य से पारित किया जाता है। वस्तुओं को संग्रहित करने वाले चरों के साथ काम करते समय, यह उन चरों को बिंदुओं के रूप में देखने में मदद करता है (क्योंकि यह मौलिक रूप से वे क्या हैं, विधानसभा स्तर पर हैं)। यदि आप एक पॉइंटर को मान से पास करते हैं, तब भी आप पॉइंटर को "ट्रेस" कर सकते हैं और इंगित की जा रही वस्तु के गुणों को संशोधित कर सकते हैं। आप जो नहीं कर सकते हैं वह एक अलग वस्तु की ओर इशारा करता है। केवल अगर आप स्पष्ट रूप से एक पैरामीटर घोषित करते हैं तो संदर्भ द्वारा पारित किया जा सकता है, क्या आप ऐसा कर पाएंगे।
फ़ंक्शंस के लिए इसका उपयोग तब करें जब आप मूल चर को केवल बदलना चाहते हैं और इसे फिर से उसी चर नाम पर लौटाते हैं, जिसके नए मान को असाइन किया गया है।
function add(&$var){ // The & is before the argument $var
$var++;
}
$a = 1;
$b = 10;
add($a);
echo "a is $a,";
add($b);
echo " a is $a, and b is $b"; // Note: $a and $b are NOT referenced
संस्करण पर निर्भर करता है, 4 मूल्य से है, 5 संदर्भ द्वारा है।