পিএইচপি-তে অ্যারেগুলি কি মান হিসাবে বা নতুন ভেরিয়েবলের রেফারেন্স হিসাবে অনুলিপি করা হয় এবং যখন ফাংশনগুলিতে পাস হয়?


259

1) কোনও অ্যারে যখন কোনও পদ্ধতি বা ফাংশনে আর্গুমেন্ট হিসাবে পাস করা হয়, তখন এটি রেফারেন্স বা মান দ্বারা পাস হয়?

2) কোনও ভেরিয়েবলের জন্য অ্যারে নির্ধারণের সময়, নতুন ভেরিয়েবলটি মূল অ্যারেটির কোনও রেফারেন্স হয়, বা এটি নতুন অনুলিপি হয়?
এটি করার বিষয়ে কী:

$a = array(1,2,3);
$b = $a;

কি $bএকটি রেফারেন্স $a?



3
@ মারলোনজেরিজআইস্লা: দেখে মনে হচ্ছে অ্যারেটি কেবলমাত্র যদি আপনি ফাংশনের অভ্যন্তরে এটি পরিবর্তন করেন তবে ক্লোন হয়। এখনও অন্য ভাষা থেকে আসছে, এটি অদ্ভুত বলে মনে হচ্ছে।
ব্যবহারকারী 276648

উত্তর:


276

আপনার প্রশ্নের দ্বিতীয় অংশের জন্য, ম্যানুয়ালটির অ্যারে পৃষ্ঠাটি দেখুন , যা বলা হয়েছে (উদ্ধৃতি) :

অ্যারে নিয়োগে সর্বদা মান অনুলিপি জড়িত। রেফারেন্স দ্বারা একটি অ্যারে অনুলিপি করতে রেফারেন্স অপারেটর ব্যবহার করুন।

এবং প্রদত্ত উদাহরণ:

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>


প্রথম অংশের জন্য, নিশ্চিত হওয়ার সর্বোত্তম উপায় হ'ল চেষ্টা করা ;-)

কোডের এই উদাহরণটি বিবেচনা করুন:

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

এটি এই আউটপুট দেবে:

array
  0 => int 10
  1 => int 20

যা সূচিত করে যে ফাংশনটি "বাইরের" অ্যারেটিকে প্যারামিটার হিসাবে পাস করা হয়েছে তা সংশোধিত হয়নি: এটি একটি অনুলিপি হিসাবে পাঠানো হয়েছে, রেফারেন্স হিসাবে নয়।

আপনি যদি এটি রেফারেন্সের মধ্য দিয়ে যেতে চান তবে আপনাকে এই পদ্ধতিটি এই পদ্ধতিতে সংশোধন করতে হবে:

function my_func(& $a) {
    $a[] = 30;
}

এবং আউটপুট হয়ে যাবে:

array
  0 => int 10
  1 => int 20
  2 => int 30

যেমন, এবার অ্যারেটি "রেফারেন্স দ্বারা" পাস করা হয়েছে।


ম্যানুয়ালটির রেফারেন্স বর্ণিত বিভাগটি পড়তে দ্বিধা করবেন না : এটি আপনার কয়েকটি প্রশ্নের উত্তর দেওয়া উচিত ;-)


$ a = & $ এটি-> এ এর ​​মতো কিছু সম্পর্কে। $ এখন কি & এর-> এটির একটি রেফারেন্স?
ফ্র্যাঙ্ক

1
আপনি যেমনটি ব্যবহার করছেন &, হ্যাঁ, এটি হওয়া উচিত - php.net/manual/en/… দেখুন
পাস্কাল মার্টিন

1
পবিত্র গাভী, আমি বিশ্বাস করতে পারি না যে আমার এই সমস্যাটি ছিল ... এটি কি একটি পাঠ হওয়া উচিত, সর্বদা
অফিঙ

2
হাই পাস্কাল, আমি খুঁজে পেয়েছি কোস্তার কন্টোসের উত্তরটি আরও সঠিক বলে মনে হচ্ছে। আমি তার সন্ধানের gist.github.com/anonymous/aaf845ae354578b74906 নিশ্চিত করার জন্য একটি সহজ দ্রুত পরীক্ষা করি আপনি কি তার সন্ধানের বিষয়ে মন্তব্য করতে পারেন?
চেওক ইয়ান চেং

1
এটি আমারও খুব সমস্যা ছিল: ভেবেছিল এটি নেস্টেড অ্যারেগুলি সম্পর্কে কিছুটা অদ্ভুত কিছু ছিল তবে এটি ঠিক ছিল পিএইচপি-তে অ্যারে অ্যাসাইনমেন্টটি কীভাবে কাজ করে।
জেরেমি তালিকা

120

আপনার প্রথম প্রশ্নের প্রসঙ্গে, অ্যারে রেফারেন্স দ্বারা পাস করা হবে UNLESS এ আপনি যে পদ্ধতিতে / ফাংশনটি কল করছেন তার মধ্যে এটি পরিবর্তন করা হয়েছে। আপনি যদি পদ্ধতি / ফাংশনের মধ্যে অ্যারে সংশোধন করার চেষ্টা করেন তবে প্রথমে এর একটি অনুলিপি তৈরি করা হয় এবং তারপরে কেবল অনুলিপিটিই সংশোধন করা হয়। এটি দেখে মনে হয় যেন অ্যারে মান দ্বারা পাস করা হয় যখন বাস্তবে এটি হয় না।

উদাহরণস্বরূপ, এই প্রথম ক্ষেত্রে, যদিও আপনি রেফারেন্স দ্বারা $ my_array গ্রহণের জন্য আপনার ফাংশনটি সংজ্ঞায়িত করছেন না (প্যারামিটার সংজ্ঞাতে & অক্ষরটি ব্যবহার করে), এটি এখনও রেফারেন্স দিয়ে পাস হবে (যেমন: আপনি স্মৃতি নষ্ট করবেন না) একটি অপ্রয়োজনীয় অনুলিপি সহ)।

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

তবে আপনি যদি অ্যারেটি সংশোধন করেন তবে প্রথমে এর একটি অনুলিপি তৈরি করা হবে (এতে আরও মেমরি ব্যবহৃত হয় তবে আপনার মূল অ্যারেটিকে প্রভাবিত করে না)।

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

এফওয়াইআই - এটি "অলস অনুলিপি" বা "অনুলিপি-অনুলিপি" নামে পরিচিত।


8
এটি একটি সুপার আকর্ষণীয় তথ্য তথ্য! দেখে মনে হচ্ছে এটি সত্য; তবে আমি এই সত্যটিকে সমর্থন করে কোনও অফিসিয়াল ডকুমেন্টেশন খুঁজে পাইনি। আমাদের পিএইচপি-র কোন সংস্করণ এই অলস অনুলিপি ধারণাকে সমর্থন করে তাও আমাদের জানতে হবে। কারও কাছে আরও তথ্য আছে?
মারিও আওয়াদ

8
আপডেট, কিছু অফিসিয়াল ডকুমেন্টেশন সন্ধান করেছে, পিএইচপি-র কোন সংস্করণটি অলস অনুলিপি সমর্থন করে তা এখনও খুঁজে পাওয়া দরকার (তারা এটিকে ম্যানুয়ালটিতে "লিখিত অনুলিপি" বলে ডাকে): php.net/manual/en/internals2.variables.intro.php
মারিও

7
এটি খালি পিএইচপি ভার্চুয়াল মেশিনের বাস্তবায়ন সিদ্ধান্ত, এবং ভাষার অংশ নয় - এটি প্রোগ্রামারটির কাছে আসলে দৃশ্যমান নয়। অনুলিপি-সম্পাদন অবশ্যই কার্য সম্পাদনের কারণে প্রস্তাবিত, কিন্তু এমন একটি প্রয়োগ যা প্রতিটি অ্যারের অনুলিপি করে প্রোগ্রামারের দৃষ্টিকোণ থেকে কোনও পার্থক্য রাখে না, তাই আমরা বলতে পারি যে ভাষা শব্দার্থবিজ্ঞানগুলি পাস-বাই-মান নির্দিষ্ট করে।
সুপারফ্লাই

14
@ অসম্পূর্ণভাবে এটি অবশ্যই একটি তাত্পর্যপূর্ণ যখন আমি জানতে চাই যে আমি স্মৃতিশক্তি না ছোঁয়া কয়েক ডজন ফাংশন দিয়ে আমার 100MB অ্যারে পাস করতে পারি কিনা! আপনি হয়ত সঠিক হতে পারেন যদিও শব্দার্থবিজ্ঞানগুলিকে পাস-বাই-ভ্যালু বলা ভাল, তবে পরিভাষাগুলির তুলনায় এ জাতীয় কবলগুলি বাদ দিয়ে এখানে বর্ণিত "বাস্তবায়ন বিশদ" অবশ্যই সত্যিকারের বিশ্বের পিএইচপি প্রোগ্রামারদের জন্য গুরুত্বপূর্ণ।
মার্ক অ্যামেরি

3
এর আরও একটি বিচক্ষণতা রয়েছে, যা সম্পাদনা সম্পর্কে চিন্তাভাবনার সময় অনুলিপি-রচনায় সচেতন হওয়া আরও গুরুত্বপূর্ণ করে তোলে। আপনি মনে করতে পারেন রেফারেন্সের মাধ্যমে অ্যারেগুলি পাস করার সাথে মানের সাথে তুলনা মেমরি বাঁচায় (যদি আপনি অনুলিপিটির বিষয়ে কপিরাইট না জানতেন) তবে এটির বিপরীত প্রভাব থাকতে পারে! অ্যারে হয়, তাহলে পরবর্তীকালে মান দ্বারা গৃহীত (আপনার নিজের বা 3 য় পক্ষের কোডের ভিত্তিতে), পিএইচপি তারপর রয়েছে একটি পূর্ণ অনুলিপি তৈরি বা এটি আর রেফারেন্স গণনা ট্র্যাক করতে পারেন! এখানে আরও: স্ট্যাকওভারফ্লো.com
ড্যান কিং

80

টি এল; ডিআর

ক) পদ্ধতি / ফাংশনটি কেবল অ্যারে আর্গুমেন্টটি পড়ায় => অন্তর্নিহিত (অভ্যন্তরীণ) রেফারেন্স
খ) পদ্ধতি / ফাংশন অ্যারে আর্গুমেন্টকে পরিবর্তন করে => মান
গ) পদ্ধতি / ফাংশন অ্যারে আর্গুমেন্টকে স্পষ্টভাবে একটি রেফারেন্স হিসাবে চিহ্নিত করা হয়েছে (একটি এম্পারস্যান্ড সহ) => সুস্পষ্ট (ব্যবহারকারী-ভূমি) রেফারেন্স

বা এটি:
- অ-অ্যাম্পারস্যান্ড অ্যারে পরম : রেফারেন্স দ্বারা পাস করা; লেখার ক্রিয়াগুলি অ্যারের একটি নতুন অনুলিপি পরিবর্তন করে, অনুলিপি যা প্রথম লেখায় তৈরি করা হয়;
- অ্যাম্পারস্যান্ড অ্যারে পরম : রেফারেন্স দ্বারা পাস; লেখার ক্রিয়াকলাপগুলি মূল অ্যারে পরিবর্তন করে।

মনে রাখবেন - নন-অ্যাম্পারস্যান্ড অ্যারে পরমকে আপনি যে মুহুর্তে লিখবেন সেই মুহুর্তে পিএইচপি একটি মান-অনুলিপি করে । এর copy-on-writeঅর্থ কি । আমি আপনাকে এই আচরণের সি উত্সটি দেখাতে চাই তবে এটি সেখানে ভয়ঙ্কর। Xdebug_debug_zval () ব্যবহার করা ভাল ।

পাস্কাল মার্টিন সঠিক ছিল। কোস্টা কনটোস তখন আরও বেশি ছিল।

উত্তর

এটা নির্ভর করে.

দীর্ঘ সংস্করণ

আমি মনে করি আমি এটি নিজের জন্য লিখছি। আমার একটি ব্লগ বা কিছু থাকা উচিত ...

যখনই লোকেরা রেফারেন্স (বা পয়েন্টারগুলি, সেই বিষয়ে) কথা বলে, তারা সাধারণত একটি লজযুক্তিতে শেষ হয় (কেবল এই থ্রেডটি দেখুন !)।
পিএইচপি একটি শ্রদ্ধেয় ভাষা হওয়ায় আমি ভেবেছিলাম আমার বিভ্রান্তি বাড়িয়ে দেওয়া উচিত (যদিও এটি উপরের উত্তরগুলির একটি সংক্ষিপ্তসার)। কারণ, যদিও একই সাথে দুজন লোক সঠিক হতে পারে তবে আপনি কেবল একটি উত্তরে তাদের মাথা ফাটিয়ে ফেলা ভাল।

প্রথমত, আপনার জানা উচিত যে আপনি কোনও প্যাডেন্ট নন যদি আপনি কালো-সাদা উপায়ে উত্তর না দেন । "হ্যাঁ / না" চেয়ে বিষয়গুলি আরও জটিল।

আপনি দেখতে পাবেন যে পুরো বাই-ভ্যালু / বাই-রেফারেন্স জিনিসটি আপনার পদ্ধতি / ফাংশন স্কোপটিতে সেই অ্যারেটি দিয়ে ঠিক কী করছেন: এর সাথে পড়া বা এটি সংশোধন করার সাথে সম্পর্কিত?

পিএইচপি কি বলে? (ওরফে "পরিবর্তন অনুসারে")

ম্যানুয়াল এই (জোর খনি) বলেছেন:

ডিফল্টরূপে, ফাংশন আর্গুমেন্টগুলি মান দ্বারা পাস হয় (যাতে যদি ফাংশনটির মধ্যে আর্গুমেন্টের মান পরিবর্তন করা হয় তবে এটি ফাংশনের বাইরে পরিবর্তন হয় না)। কোনও ফাংশনকে তার তর্কগুলি সংশোধন করার অনুমতি দেওয়ার জন্য , তাদের অবশ্যই রেফারেন্স দিয়ে পাস করতে হবে ।

সর্বদা রেফারেন্স দিয়ে কোনও ক্রিয়াকলাপের পক্ষে যুক্তি অর্জনের জন্য, ফাংশন সংজ্ঞাতে আর্গুমেন্টের নামে একটি অ্যাম্পারস্যান্ড (&) প্রিপেন্ড করুন

যতদূর আমি বলতে পারি, যখন বড়, গুরুতর, সৎ-থেকে-গড প্রোগ্রামাররা রেফারেন্স সম্পর্কে কথা বলেন, তারা সাধারণত সেই রেফারেন্সের মান পরিবর্তন করার বিষয়ে কথা বলেন । এবং যে ঠিক কি সম্পর্কে ম্যানুয়াল আলোচনা আছে: hey, if you want to CHANGE the value in a function, consider that PHP's doing "pass-by-value"

আরও একটি মামলা রয়েছে যা তারা উল্লেখ করেনি, যদিও: আমি যদি কিছু পরিবর্তন না করি - কেবল পড়ুন?
আপনি যদি এমন পদ্ধতিতে অ্যারে পাস করেন যা স্পষ্টভাবে একটি রেফারেন্স চিহ্নিত করে না, এবং আমরা ফাংশনের সুযোগে সেই অ্যারেটি পরিবর্তন করি না? উদাহরণ:

<?php
function readAndDoStuffWithAnArray($array) 
{
    return $array[0] + $array[1] + $array[2];
}

$x = array(1, 2, 3);

echo readAndDoStuffWithAnArray($x);

আমার সহযাত্রী পড়ুন।

পিএইচপি আসলে কি করে? (ওরফে "স্মৃতি অনুসারে")

একই বড় এবং গুরুতর প্রোগ্রামাররা যখন তারা আরও গুরুতর হয়ে ওঠে, তখন তারা রেফারেন্সের ক্ষেত্রে "মেমরি অপটিমাইজেশন" সম্পর্কে কথা বলে। পিএইচপি করে। কারণ PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting, তাই

বিভিন্ন ক্রিয়াকলাপে বিশাল আরেগুলি পাস করা এবং পিএইচপি তাদের অনুলিপি তৈরি করা আদর্শ হবে না (সর্বোপরি "পাস-বাই-মান" এটি করে):

<?php

// filling an array with 10000 elements of int 1
// let's say it grabs 3 mb from your RAM
$x = array_fill(0, 10000, 1); 

// pass by value, right? RIGHT?
function readArray($arr) { // <-- a new symbol (variable) gets created here
    echo count($arr); // let's just read the array
}

readArray($x);

ঠিক আছে এখন, যদি এটি আসলে পাস-বাই-ভ্যালু হত তবে আমাদের প্রায় 3 এমবি + র‌্যাম যেতে হত, কারণ সেই অ্যারের দুটি অনুলিপি আছে, তাই না ?

ভুল। যতক্ষণ না আমরা $arrভেরিয়েবলটি পরিবর্তন করি না , এটি একটি রেফারেন্স, স্মৃতি ভিত্তিক । আপনি শুধু এটি দেখতে না। এটা কেন পিএইচপি এর উল্লেখ ব্যবহারকারী-জমি রেফারেন্স যখন কথা বলছেন &$someVar, অভ্যন্তরীণ এবং স্পষ্ট (এম্পারসেন্ড সঙ্গে) বেশী মাঝে পার্থক্যটা উল্লেখ করা।

তথ্য

সুতরাং, when an array is passed as an argument to a method or function is it passed by reference?

আমি তিনটি (হ্যাঁ, তিনটি) কেস নিয়ে এসেছি :
ক) পদ্ধতি / ফাংশনটি কেবল অ্যারে আর্গুমেন্টটি পড়ে
খ) পদ্ধতি / ফাংশন অ্যারে যুক্তিটি সংশোধন করে
গ) পদ্ধতি / ফাংশন অ্যারে যুক্তিটি স্পষ্টভাবে একটি রেফারেন্স হিসাবে চিহ্নিত করা হয়েছে (একটি সহ) এম্পারসেন্ড)


প্রথমত, আসুন দেখুন অ্যারে আসলে কত মেমরি খায় ( এখানে রান করুন ):

<?php
$start_memory = memory_get_usage();
$x = array_fill(0, 10000, 1);
echo memory_get_usage() - $start_memory; // 1331840

যে অনেক বাইট। গ্রেট।

ক) পদ্ধতি / ফাংশন কেবল অ্যারে আর্গুমেন্টটি পড়ে

এখন আসুন একটি ফাংশন তৈরি করুন যা কেবলমাত্র যুক্তিটিকে আর্গুমেন্ট হিসাবে পড়বে এবং আমরা দেখব যে পড়ার যুক্তিটি কতটা স্মৃতি গ্রহণ করে:

<?php

function printUsedMemory($arr) 
{
    $start_memory = memory_get_usage();

    count($arr);       // read
    $x = $arr[0];      // read (+ minor assignment)
    $arr[0] - $arr[1]; // read

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1); // this is 1331840 bytes
printUsedMemory($x);

অনুমান করতে চান? আমি 80 পেয়েছি! নিজের জন্য দেখুন । এই অংশটি পিএইচপি ম্যানুয়াল বাদ দেয়। যদি $arrপরমটি আসলে-দ্বারা-মানটি পাস করত তবে আপনি 1331840বাইটগুলির মতো কিছু দেখতে পেতেন। মনে হয় $arrরেফারেন্সের মতো আচরণ করে, তাই না? কারণ এটি এটা হল একটি অভ্যন্তরীণ এক - একটি রেফারেন্স।

খ) পদ্ধতি / ফাংশন অ্যারে যুক্তি সংশোধন করে

এখন, আসুন সেই পরম থেকে এটি পড়ার পরিবর্তে লিখি :

<?php

function printUsedMemory($arr)
{
    $start_memory = memory_get_usage();

    $arr[0] = 1; // WRITE!

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1);
printUsedMemory($x);

আবার, নিজের জন্য দেখুন , আমার জন্য, এই ক্ষেত্রে 1331840. তাই হচ্ছে যে চমত্কার বন্ধ, কিন্তু অ্যারের হয় আসলে কপি করা হচ্ছে $arr

গ) পদ্ধতি / ফাংশন অ্যারে আর্গুমেন্টটি স্পষ্টভাবে একটি রেফারেন্স হিসাবে চিহ্নিত করা হয়েছে (একটি এম্পারস্যান্ড সহ)

এখন আসুন দেখা যাক স্পষ্টতাত্ত রেফারেন্সের জন্য রাইটিং অপারেশনটি কত স্মৃতি নেয় ( এখানে রান করুন ) - ফাংশনের স্বাক্ষরে এম্পারস্যান্ডটি নোট করুন:

<?php

function printUsedMemory(&$arr) // <----- explicit, user-land, pass-by-reference
{
    $start_memory = memory_get_usage();

    $arr[0] = 1; // WRITE!

    echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading
}

$x = array_fill(0, 10000, 1);
printUsedMemory($x);

আমার বাজি আপনি 200 সর্বোচ্চ পান! সুতরাং এটি অ-অ্যাম্পারস্যান্ড পরম থেকে পড়ার মতো প্রায় মেমরি খায় ।


একটি স্মৃতি ফাঁস ডিবেগ আমার কয়েক ঘন্টা সংরক্ষণ!
Ragen Dazs

2
কোস্টা কনটোস: এটি এমন একটি গুরুত্বপূর্ণ প্রশ্ন যা আপনার এটি গ্রহণযোগ্য উত্তর হিসাবে চিহ্নিত করা উচিত। এটি বলেছিল, @ নিউভারমাইন্ড: দুর্দান্ত প্রবন্ধ, তবে দয়া করে একটি শীর্ষ টিএল; ডিআর বিভাগ অন্তর্ভুক্ত করুন।
এভিআইডিপ্লোয়ার

1
@ নিউভারমাইন্ড: আমি একটি সংক্ষিপ্ত আকারের ছদ্মবেশী নই, প্রধান পার্থক্যটি হ'ল সমাপ্তি সাধারণত একটি নিবন্ধের শেষে উপস্থিত হয়, যখন টিএল; ডিআর তাদের প্রথম সারিরূপে উপস্থিত হয় যাদের দীর্ঘ বিশ্লেষণের পরিবর্তে কেবল সংক্ষিপ্ত জবাব দরকার for । আপনার গবেষণা ভাল এবং এটি সমালোচনা নয়, কেবল আমার $ 00.02।
এভিআইডিপোপার

1
তুমি ঠিক বলছো. আমি সিদ্ধান্তগুলি শীর্ষে রেখেছি। তবে আমি এখনও চাই যে কোনও সিদ্ধান্তে পৌঁছানোর আগে লোকেরা পুরো জিনিসটি পড়তে অলস হওয়া বন্ধ করে দেয় । জিনিসগুলির ক্রম পরিবর্তন করার জন্য আমাদের পক্ষে স্ক্রোলিং খুব সহজ।
নেভভারমাইন্ড

1
আমার ধারণা পিএইচপি অনেক বছর পরে আরও দক্ষ হয়েছে কারণ আপনার কোডপ্যাড উদাহরণগুলি অনেক কম নম্বর দেয় :)
ড্রাজস us

14

গতানুগতিক

  1. প্রিমিটিভগুলি মান দ্বারা পাস হয়। জাভা থেকে ভিন্ন, স্ট্রিং পিএইচপি মধ্যে আদিম
  2. আদিমদের অ্যারেগুলি মান দ্বারা পাস হয়
  3. বিষয়গুলি রেফারেন্স দিয়ে পাস হয়
  4. অবজেক্টের অ্যারেগুলি মান (অ্যারে) দ্বারা পাস করা হয় তবে প্রতিটি বস্তু রেফারেন্স দ্বারা পাস হয়।

    <?php
    $obj=new stdClass();
    $obj->field='world';
    
    $original=array($obj);
    
    
    function example($hello) {
        $hello[0]->field='mundo'; // change will be applied in $original
        $hello[1]=new stdClass(); // change will not be applied in $original
        $
    }
    
    example($original);
    
    var_dump($original);
    // array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } } 

দ্রষ্টব্য: একটি অপ্টিমাইজেশন হিসাবে, প্রতিটি একক মানটি ফাংশনের অভ্যন্তরে পরিবর্তিত হওয়া পর্যন্ত রেফারেন্স হিসাবে পাস করা হয়। যদি এটি সংশোধিত হয় এবং মানটি রেফারেন্স অনুসারে পাস করা হয় তবে এটি অনুলিপি করা হয় এবং অনুলিপিটি সংশোধিত হয়।


4
এই উত্তরটি শীর্ষে +1 করা উচিত। এটিতে একটি অস্পষ্ট গোচা রয়েছে যা অন্যান্য উত্তরগুলি উল্লেখ করে না: "4 - অবজেক্টের অ্যারে মান (অ্যারে) দ্বারা পাস করা হয় তবে প্রতিটি বস্তু রেফারেন্স দিয়ে পাস হয়।" আমি সেটার কারণে আমার মাথা আঁচড়াচ্ছিলাম!
অগাস্টিন

@ ম্যাগল্লেনসকে আমার জন্য প্রথমে রেট দেওয়া উচিত, আপনি আমার কাছে থাকা অবজেক্ট অ্যারেটির একটি ঝামেলা পরিষ্কার করলেন। দুটি অ্যারে ভেরিয়েবলের (মূল এবং অনুলিপি) একটির মধ্যে কোন অ্যারেতে কোনও বস্তু সংশোধন করার কোনও উপায় আছে কি?
ফেডারেশন 72বাড়ি

5

যখন কোনও অ্যারে পিএইচপি-তে কোনও পদ্ধতি বা ফাংশনে প্রেরণ করা হয়, আপনি মান হিসাবে স্পষ্টভাবে রেফারেন্স দিয়ে না দিয়ে মান দ্বারা পাস করা হয়, যেমন:

function test(&$array) {
    $array['new'] = 'hey';
}

$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

আপনার দ্বিতীয় প্রশ্নে, $bকোনও রেফারেন্স নয় $a, এর একটি অনুলিপি $a

অনেকটা প্রথম উদাহরণের মতো, আপনি $aনিম্নলিখিতগুলি দ্বারা রেফারেন্স করতে পারেন :

$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

1

এই থ্রেডটি কিছুটা পুরনো তবে এখানে আমি সবেমাত্র এসেছি:

এই কোড ব্যবহার করে দেখুন:

$date = new DateTime();
$arr = ['date' => $date];

echo $date->format('Ymd') . '<br>';
mytest($arr);
echo $date->format('Ymd') . '<br>';

function mytest($params = []) {
    if (isset($params['date'])) {
        $params['date']->add(new DateInterval('P1D'));
    }
}

http://codepad.viper-7.com/gwPYMw

নোট করুন $ প্যারামগুলির প্যারামিটারের জন্য কোনও অ্যাম্প নেই এবং এখনও এটি $ আরার ['তারিখ'] এর মান পরিবর্তন করে। এটি এখানে অন্যান্য সমস্ত ব্যাখ্যার সাথে সত্যই মেলে না এবং আমি এখন অবধি যা ভাবছিলাম with

যদি আমি $ প্যারামগুলি ['তারিখ'] অবজেক্টটি ক্লোন করি তবে ২ য় আউটপুটড তারিখ একই থাকে। যদি আমি এটি কেবল একটি স্ট্রিংয়ে সেট করি তবে এটি আউটপুটকেও প্রভাবিত করে না।


3
অ্যারেটি অনুলিপি করা হয়েছে, তবে এটি কোনও গভীর অনুলিপি নয়। এর অর্থ হ'ল সংখ্যা এবং স্ট্রিংয়ের মতো আদিম মানগুলি m পরম এ অনুলিপি করা হয়েছে, তবে বস্তুর জন্য, রেফারেন্সটি অবজেক্টটিকে ক্লোন করার পরিবর্তে অনুলিপি করা হয়েছে। $ আরআর $ তারিখের জন্য একটি রেফারেন্স ধারণ করে এবং অনুলিপি করা অ্যারে ms প্যারামগুলিও তাই। সুতরাং আপনি যখন value প্যারামগুলিতে ['তারিখ'] তে কোনও ফাংশন কল করেন যা এর মান পরিবর্তন করে, আপনি $ আরআর ['তারিখ'] এবং $ তারিখও পরিবর্তন করেন। আপনি যখন কোনও স্ট্রিংয়ে $ প্যারামগুলি ['তারিখ'] সেট করেন, আপনি কেবলমাত্র something তারিখের সাথে ms প্যারামের রেফারেন্সটি অন্য কিছু দিয়ে প্রতিস্থাপন করছেন।
এজেগ

1

উত্তরের একটি প্রসারিত করার জন্য, বহুমাত্রিক অ্যারেগুলির সাববারিগুলি রেফারেন্সের মাধ্যমে স্পষ্টভাবে পাস না করে মান দ্বারা পাস করা হয়।

<?php
$foo = array( array(1,2,3), 22, 33);

function hello($fooarg) {
  $fooarg[0][0] = 99;
}

function world(&$fooarg) {
  $fooarg[0][0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

ফলাফল হলো:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(66)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}

0

পিএইচপি-তে অ্যারেগুলি ডিফল্টরূপে মান অনুসারে ফাংশনগুলিতে প্রেরণ করা হয়, যদি না আপনি নীচের স্নিপেট হিসাবে স্পষ্ট করে রেফারেন্সের মাধ্যমে সেগুলি পাস করেন:

$foo = array(11, 22, 33);

function hello($fooarg) {
  $fooarg[0] = 99;
}

function world(&$fooarg) {
  $fooarg[0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

এখানে ফলাফল:

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  int(66)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.