অন্য কোনও পিএইচপি অ্যারের অনুলিপি তৈরি করার কোনও ফাংশন আছে?


529

অন্য কোনও পিএইচপি অ্যারের অনুলিপি তৈরি করার কোনও ফাংশন আছে?

পিএইচপি অ্যারে অনুলিপি করার চেষ্টা করে আমি কয়েক বার পোড়া হয়েছি। আমি কোনও বস্তুর অভ্যন্তরের সংজ্ঞায়িত অ্যারে এর বাইরে গ্লোবালটিতে অনুলিপি করতে চাই।


সত্যিই দেরি হয়ে গেছে, তবে আমার পরিবেশে আমি এটি পরীক্ষা করেছি (এবং এটি কাজ করেছে): ফাংশন অ্যারেকপি (অ্যারে $ এ) $ রিটার্ন $ এ; } $ a1 = অ্যারে (); ($ i = 0; $ i <3; $ i ++) {$ a1 ["কী- $ i"] = "মান # $ i"; ; $ a1 ["কী-সাব-অ্যারে"] = অ্যারে (1, 2, 3, 4); $ a2 = $ a1; $ a3 = অ্যারেকপি ($ এ 1); (is i = 0; $ i <3; $ i ++) {যদি (! is_array ($ a2 ["কী- $ i"])) {$ a2 ["key- $ i"] = "পরিবর্তিত মান # $ আমি "; }} $ a2 ["কী-সাব-অ্যারে"] = অ্যারে ("সাব-অ্যারে পরিবর্তিত 1", "সাব-অ্যারে পরিবর্তিত 2"); , var_dump ($ A1); , var_dump ($ A2); , var_dump ($ A3); কৌতুক, হয় ফাংশন মধ্যে একটি রেফারেন্স হিসাবে ;-) অ্যারের পাস না
সেভেন

উত্তর:


926

পিএইচপি-তে অ্যারেগুলি অনুলিপি দ্বারা নির্ধারিত হয়, যখন অবজেক্টগুলি রেফারেন্স দ্বারা নির্ধারিত হয়। এই যে মানে:

$a = array();
$b = $a;
$b['foo'] = 42;
var_dump($a);

ফলন হবে:

array(0) {
}

যেখানে:

$a = new StdClass();
$b = $a;
$b->foo = 42;
var_dump($a);

উৎপাদনের:

object(stdClass)#1 (1) {
  ["foo"]=>
  int(42)
}

আপনি যেমন জটিল হিসাবে বিভ্রান্ত হতে পারে ArrayObject, এটি এমন একটি বস্তু যা ঠিক অ্যারের মতোই কাজ করে। তবে একটি বস্তু হওয়ার কারণে এটিতে শব্দার্থবিজ্ঞানের উল্লেখ রয়েছে।

সম্পাদনা করুন: @ অ্যান্ড্রুলারসন নীচের মন্তব্যে একটি বক্তব্য উত্থাপন করেছেন। পিএইচপি'র "রেফারেন্স" নামে একটি বিশেষ বৈশিষ্ট্য রয়েছে। এগুলি সি / সি ++ এর মতো ভাষার পয়েন্টারগুলির সাথে কিছুটা মিল তবে একেবারে এক নয়। যদি আপনার অ্যারেতে রেফারেন্স থাকে তবে অ্যারে নিজেই অনুলিপি দ্বারা পাস করার পরে, রেফারেন্সগুলি এখনও মূল টার্গেটে সমাধান করবে। এটি অবশ্যই পছন্দসই আচরণ, তবে আমি মনে করি এটি উল্লেখযোগ্য।


104
আপনি প্রশ্নের উত্তর না। আপনি কেবল সমস্যাটি ব্যাখ্যা করেছেন। কোনটি, ওপিটির পক্ষে, সম্ভবত তিনি যা খুঁজছিলেন। তবে, আমার (এবং অন্যরাও), প্রায় চার বছর পরে এখানে একই ধরণের সমস্যার সাথে আসছেন, মূল অ্যারেটি সংশোধন না করে আমার কাছে এখনও অ্যারে ক্লোন করার ভাল উপায় নেই (এতে অভ্যন্তরীণ পয়েন্টারও রয়েছে)। আমি মনে করি আমার নিজের প্রশ্নটি করার সময় এসেছে।
অ্যান্ড্রু লারসন

28
@ অ্যান্ড্রুলারসন তবে পিএইচপি ডিফল্টরূপে এটি করে - এটি এর মূল বক্তব্য। রেফারেন্সগুলি যদিও সমাধান করা হয় না, সুতরাং আপনার যদি এটির প্রয়োজন হয় তবে আপনাকে পুনরাবৃত্তভাবে অ্যারেটি অতিক্রম করতে হবে এবং একটি নতুন তৈরি করতে হবে - একইভাবে, যদি উত্স অ্যারেতে অবজেক্ট থাকে এবং আপনি সেই ক্লোনটি চান তবে আপনাকে ম্যানুয়ালি এটি করতে হবে। এই বিষয়টিও মনে রাখবেন যে পিএইচপি-তে রেফারেন্স সি-র পয়েন্টারগুলির মতো নয় , আপনার ক্ষেত্রে সম্পর্কে কিছু না জেনেও আমি পরামর্শ দিতে পারি যে প্রথম ক্ষেত্রে রেফারেন্সের অ্যারে রাখা আশ্চর্যজনক, বিশেষত যদি আপনি চিকিত্সা করার ইচ্ছা না রাখেন রেফারেন্স হিসাবে তাদের? ব্যবহারের ক্ষেত্রে কী?
Troelskn

1
: @troelskn আমি আমার সমস্যার একটি সমাধান সঙ্গে এই প্রশ্নের উত্তর যোগ stackoverflow.com/a/17729234/1134804
অ্যান্ড্রু Larsson

3
কিন্তু যখন এটি পছন্দসই আচরণ নয় তখন কী হবে? প্রশ্ন কিভাবে করতে জিজ্ঞেস করল গভীর কপি। এটি অবশ্যই পছন্দসই নয়। আপনার উত্তর চেয়ে উত্তম: $copy = $original;। অ্যারে উপাদানগুলি রেফারেন্স হলে যা কাজ করে না।
doug65536

8
সর্বদা হিসাবে phpআমাদের সর্বনিম্ন প্রত্যাশিত ফলাফল উপস্থাপন করে , কারণ এই সমাধানটি সর্বদা কার্যকর হয় না$a=array(); $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];প্রিন্ট করার array0সময় $a=$GLOBALS; $b=$a; $b["x"]=0; $c=$b; $b["x"]=1; echo gettype($b), $c["x"];প্রিন্ট array1। সম্ভবত কিছু অ্যারে রেফারেন্স দ্বারা অনুলিপি করা হয়।
টিনো

186

পিএইচপি ডিফল্টভাবে অ্যারের অনুলিপি করবে। পিএইচপি-তে রেফারেন্সগুলি স্পষ্ট করতে হবে।

$a = array(1,2);
$b = $a; // $b will be a different array
$c = &$a; // $c will be a reference to $a

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

11
@robsch - প্রোগ্রামের যুক্তির স্তরে অ্যারে অনুলিপি করা হয়। তবে মেমোরিতে, এটি সংশোধন না করা পর্যন্ত এটি আসলে অনুলিপি করা হবে না - কারণ পিএইচপি সমস্ত প্রকারের জন্য অনুলিপি-অন-লিখিত শব্দার্থ ব্যবহার করে। stackoverflow.com/questions/11074970/…
জেসিকা নাইট

@ কোরেইকনাইট জেনে রাখা ভাল। এই জন্য আপনাকে ধন্যবাদ.
রোবস

4
মনে রাখবেন যে নেস্টেড অ্যারেগুলির জন্য এটি সত্য নয়, তারা উল্লেখযোগ্য এবং তাই আপনি একটি ভাঙ্গা
জগাখিচির

45

যদি আপনার কাছে এমন অ্যারে থাকে যাতে অবজেক্ট থাকে, আপনাকে সেই অ্যারের অভ্যন্তরীণ পয়েন্টারটি স্পর্শ না করেই তার অনুলিপি তৈরি করতে হবে এবং আপনার সমস্ত বস্তু ক্লোন করা প্রয়োজন (যাতে আপনি অনুলিপিগুলিতে পরিবর্তনগুলি করার সময় মূলগুলি পরিবর্তন করছেন না অ্যারে), এটি ব্যবহার করুন।

অ্যারের অভ্যন্তরীণ পয়েন্টারটি স্পর্শ না করার কৌশলটি হ'ল আপনি অ্যারের অনুলিপিটি নিয়ে কাজ করছেন তা নিশ্চিত করা, এবং মূল অ্যারে (বা এটির কোনও রেফারেন্স) নয়, সুতরাং একটি ফাংশন প্যারামিটার ব্যবহার করে কাজটি সম্পন্ন হবে (এইভাবে, এটি একটি ফাংশন যা অ্যারে নেয়)।

মনে রাখবেন যে আপনার এখনও প্রয়োগ করতে হবে তাদের সম্পত্তিগুলি ক্লোন করতে চান তবে আপনার অবজেক্টগুলিতে __Cone ()

এই ফাংশনটি কোনও ধরণের অ্যারে (মিশ্রিত প্রকার সহ) এর জন্য কাজ করে।

function array_clone($array) {
    return array_map(function($element) {
        return ((is_array($element))
            ? array_clone($element)
            : ((is_object($element))
                ? clone $element
                : $element
            )
        );
    }, $array);
}

1
মনে রাখবেন যে এটি কিছু বিশেষ ক্ষেত্রে। এছাড়াও, নোট করুন যে এটি কেবল প্রথম স্তরের রেফারেন্সগুলি ক্লোন করবে। আপনার যদি একটি গভীর অ্যারে থাকে তবে আপনি গভীর নোডগুলি ক্লোন করে পাবেন না, যদি সেগুলি উল্লেখ থাকে। আপনার ক্ষেত্রে সমস্যা হতে পারে না, তবে এটি কেবল মনে রাখবেন।
Troelskn

4
@ ট্রোলস্কন আমি কিছু পুনরাবৃত্তি যোগ করে এটি ঠিক করেছি। এই ফাংশনটি এখন মিশ্রিত প্রকারগুলি সহ যে কোনও ধরণের অ্যারেগুলিতে কাজ করবে। এটি সরল অ্যারেগুলির জন্য ঠিক পাশাপাশি কাজ করে, তাই এটি আর স্থানীয়ীকৃত হয় না। এটি মূলত একটি সর্বজনীন অ্যারে ক্লোনিং মেশিন। আপনার বস্তুগুলি গভীর থাকলে তারা আপনাকে এখনও___ক্লোন () ফাংশনটি সংজ্ঞায়িত করতে হবে তবে এটি এই ফাংশনের "সুযোগ" এর বাইরে নয় (খারাপ পাপের জন্য দুঃখিত)।
অ্যান্ড্রু লারসন

2
আমি দৃ strongly়ভাবে বিশ্বাস করি যে এটি এই প্রশ্নের আসল উত্তর, কেবলমাত্র একমাত্র উপায় যা সত্যই গভীরভাবে একটি অ্যারে অনুলিপি করতে দেখেছে যাতে অবজেক্ট রয়েছে।
প্যাট্রিক

এটি অবজেক্টের বৈশিষ্ট্যগুলিকে পুনরাবৃত্তি করে না যাতে অন্যান্য অ্যারে এবং রেফারেন্সযুক্ত সামগ্রী থাকতে পারে।
ya.teck

6
এই ব্যবহার __FUNCTION__উজ্জ্বল।
zessx

29

যখন তুমি কর

$array_x = $array_y;

পিএইচপি অ্যারে অনুলিপি করে, সুতরাং আপনি কীভাবে জ্বলতে পারতেন তা আমি নিশ্চিত নই। আপনার ক্ষেত্রে,

global $foo;
$foo = $obj->bar;

ভাল কাজ করা উচিত।

পুড়ে যাওয়ার জন্য, আমি মনে করি আপনি হয় রেফারেন্স ব্যবহার করে বা অ্যারের ভিতরে থাকা কোনও জিনিসকে ক্লোন করার আশা করছেন।



20

array_merge() এমন একটি ফাংশন যা আপনি পিএইচপি-তে অন্য একটি অ্যারে অনুলিপি করতে পারেন।


4
হ্যাঁ, তবে কীগুলি সংশোধন করা হবে, উদ্ধৃতি: সংখ্যার কীগুলির সাথে ইনপুট অ্যারের মানগুলি ফলাফল অ্যারেতে শূন্য থেকে শুরু করে ইনক্রিমেন্টিং কীগুলির সাথে পুনর্নবীকরণ করা হবে।
zamnuts

কী বজায় রাখার জন্য @zamnuts: $a_c = array_combine(array_keys($a), array_values($a))
সিপিএইচপিথন

18

সরল এবং সমস্ত লিঙ্ক ভাঙা গভীর অনুলিপি তৈরি করে

$new=unserialize(serialize($old));

4
সাধারণত এটি কার্যকর হয় তবে কিছু ক্ষেত্রে এটি ব্যতিক্রম হতে পারে কারণ সমস্ত ভেরিয়েবল সিরিয়ালযোগ্য হয় না (উদাহরণস্বরূপ ক্লোজার এবং ডাটাবেস সংযোগ) connections
ya.teck

আরেকটি বিষয় লক্ষণীয় হ'ল কোনও শ্রেণি __ওয়াকআপ যাদু পদ্ধতি প্রয়োগ করে যদি অবজেক্টের রেফারেন্সগুলি পুনরুদ্ধার করা যায়।
ya.teck

ধন্যবাদ, পরিশেষে এমন কিছু যা সত্যই কাজ করে, অন্যান্য বলক জবাবগুলি প্রচুর পরিমাণে সমীক্ষা করে না, তারা অবশ্যই বস্তুর অ্যারে নিয়ে কাজ করেনি যেমন প্রশ্নে নির্দিষ্ট করা হয়েছে যে অ্যারেতে উপাদানগুলির সংখ্যা পরিবর্তিত হতে পারে, তবে সুনির্দিষ্টভাবে উল্লেখগুলি রেফারেন্স নয় তাদের ভিতরে অবজেক্টস
FentomX1

12

আমি array_replace(বা array_replace_recursive) পছন্দ করি ।

$cloned = array_replace([], $YOUR_ARRAY);

এটি Object.assignজাভাস্ক্রিপ্ট থেকে মত কাজ করে।

$original = [ 'foo' => 'bar', 'fiz' => 'baz' ];

$cloned = array_replace([], $original);
$clonedWithReassignment = array_replace([], $original, ['foo' => 'changed']);
$clonedWithNewValues = array_replace([], $original, ['add' => 'new']);

$original['new'] = 'val';

ফলাফল হবে

// original: 
{"foo":"bar","fiz":"baz","new":"val"}
// cloned:   
{"foo":"bar","fiz":"baz"}
// cloned with reassignment:
{"foo":"changed","fiz":"baz"}
// cloned with new values:
{"foo":"bar","fiz":"baz","add":"new"}

1
কী array_slice($arr, 0)বা আপনি কী সম্পর্কে চিন্তা করবেন না, যখন array_values($arr)? আমি ভাবছি তারা অ্যারে অনুসন্ধানের চেয়ে দ্রুত হতে পারে। এছাড়াও, জাভাস্ক্রিপ্টে Array.slice()অ্যারে ক্লোন করার জন্য এটি বেশ জনপ্রিয় ।
খ্রিস্টান

জেএস-এ আমাদের কী-মান- জোড় এবং অ্যারের জন্য অবজেক্ট রয়েছে । পিএইচপি এই পার্থক্য তৈরি করে না। সংখ্যাযুক্ত সূচী সহ পিএইচপি অ্যারেগুলির জন্য এবং এখানে উল্লিখিত অন্যান্য সমস্ত পদ্ধতি খুব ভালভাবে কাজ করে। তবে আপনি যদি কয়েকটি কী-মান-জুটি মার্জ করতে চান (যেমন এটি জেএস-অবজেক্টগুলির মাধ্যমে বা স্প্রেড-সিনট্যাক্সের মাধ্যমেও সম্ভব ) তবে আরও কার্যকর হতে পারে। array_sliceObject.assignarray_replace
পুতজী সান

@ ক্রিশ্চিয়ান array_values()আমার ব্যবহারের ক্ষেত্রে সঠিকভাবে কাজ করার পরামর্শের জন্য আপনাকে ধন্যবাদ জানায় ।
বিগসি

11

আপনার অ্যারেতে যদি কেবলমাত্র প্রাথমিক ধরণ থাকে তবে আপনি এটি করতে পারেন:

$copy = json_decode( json_encode($array), true);

আপনার রেফারেন্সগুলি ম্যানুয়ালি আপডেট করার দরকার নেই
আমি জানি এটি সবার জন্য কার্যকর হবে না তবে এটি আমার পক্ষে কাজ করেছে


4
+1 এটি করা সত্যিই খারাপ জিনিস, তবে প্রযুক্তিগতভাবে সঠিক এবং চতুর। আমি যদি কোডটিতে এটি দেখতে পাই তবে আমি খেজুরের মুখোমুখি হব তবে আমি সহায়তা করতে পারছি না তবে এটি পছন্দ করতে পারে।
বিক্রিয়াকারী

4

যেহেতু এটি কোনও উত্তরের মধ্যে আচ্ছাদিত ছিল না এবং এখন পিএইচপি 5.3 এ উপলব্ধ (ধারণা করা হয়েছে যে আসল পোস্টটি 5.2 ব্যবহার করছে)।

একটি অ্যারের কাঠামো বজায় রাখতে এবং এর মান পরিবর্তন করতে আমি ব্যবহার করতে পছন্দ করি array_replaceবা array_replace_recursiveআমার ব্যবহারের ক্ষেত্রে নির্ভর করে।

http://php.net/manual/en/function.array-replace.php

এটি ব্যবহার array_replaceএবং array_replace_recursiveপ্রদর্শনের একটি উদাহরণ যা এটি সূচকযুক্ত আদেশ বজায় রাখতে সক্ষম এবং একটি রেফারেন্স অপসারণ করতে সক্ষম।

http://ideone.com/SzlBUZ

নীচের কোডটি পিএইচপি 5.4 থেকে পাওয়া সংক্ষিপ্ত অ্যারে সিনট্যাক্স ব্যবহার করে লেখা হয়েছে যা এর সাথে প্রতিস্থাপন array()করে []http://php.net/manual/en/language.types.array.php

উভয় অফসেট ইনডেক্সড এবং নাম সূচকযুক্ত অ্যারেগুলিতে কাজ করে

$o1 = new stdClass;
$a = 'd';
//This is the base array or the initial structure
$o1->ar1 = ['a', 'b', ['ca', 'cb']];
$o1->ar1[3] = & $a; //set 3rd offset to reference $a

//direct copy (not passed by reference)
$o1->ar2 = $o1->ar1; //alternatively array_replace($o1->ar1, []);
$o1->ar1[0] = 'z'; //set offset 0 of ar1 = z do not change ar2
$o1->ar1[3] = 'e'; //$a = e (changes value of 3rd offset to e in ar1 and ar2)

//copy and remove reference to 3rd offset of ar1 and change 2nd offset to a new array
$o1->ar3 = array_replace($o1->ar1, [2 => ['aa'], 3 => 'd']);

//maintain original array of the 2nd offset in ar1 and change the value at offset 0
//also remove reference of the 2nd offset
//note: offset 3 and 2 are transposed
$o1->ar4 = array_replace_recursive($o1->ar1, [3 => 'f', 2 => ['bb']]);

var_dump($o1);

আউটপুট:

["ar1"]=>
  array(4) {
    [0]=>
    string(1) "z"
    [1]=>
    string(1) "b"
    [2]=>
    array(2) {
      [0]=>
      string(2) "ca"
      [1]=>
      string(2) "cb"
    }
    [3]=>
    &string(1) "e"
  }
  ["ar2"]=>
  array(4) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    array(2) {
      [0]=>
      string(2) "ca"
      [1]=>
      string(2) "cb"
    }
    [3]=>
    &string(1) "e"
  }
  ["ar3"]=>
  array(4) {
    [0]=>
    string(1) "z"
    [1]=>
    string(1) "b"
    [2]=>
    array(1) {
      [0]=>
      string(2) "aa"
    }
    [3]=>
    string(1) "d"
  }
  ["ar4"]=>
  array(4) {
    [0]=>
    string(1) "z"
    [1]=>
    string(1) "b"
    [2]=>
    array(2) {
      [0]=>
      string(2) "bb"
      [1]=>
      string(2) "cb"
    }
    [3]=>
    string(1) "f"
  }

3

আমি এটি অনেক দিন আগে জানি তবে এটি আমার পক্ষে কাজ করেছে ..

$copied_array = array_slice($original_array,0,count($original_array));

2

এইভাবে আমি পিএইচপি তে আমার অ্যারেগুলি অনুলিপি করছি:

function equal_array($arr){
  $ArrayObject = new ArrayObject($arr);
  return $ArrayObject->getArrayCopy();  
}

$test = array("aa","bb",3);
$test2 = equal_array($test);
print_r($test2);

এই ফলাফলগুলি:

Array
(
[0] => aa
[1] => bb
[2] => 3
)

2
কেন শুধু বলছেন না $test2 = $test;? ArrayObjectএখানে কোন সমস্যার সমাধান হচ্ছে ?
Nate

1
<?php
function arrayCopy( array $array ) {
        $result = array();
        foreach( $array as $key => $val ) {
            if( is_array( $val ) ) {
                $result[$key] = arrayCopy( $val );
            } elseif ( is_object( $val ) ) {
                $result[$key] = clone $val;
            } else {
                $result[$key] = $val;
            }
        }
        return $result;
}
?>

1

আমি খুঁজে পাওয়া সবচেয়ে নিরাপদ এবং সস্তার উপায় হ'ল:

<?php 
$b = array_values($a);

এটি অ্যারে পুনর্নির্মাণ করার সুবিধাও রয়েছে।

এটি এসোসিয়েটিভ অ্যারে (হ্যাশ) এ প্রত্যাশার মতো কাজ করবে না তবে পূর্ববর্তী উত্তরগুলির বেশিরভাগই নয়।


1

অ্যারেঅবজেক্টের একটি অনুলিপি তৈরি করে

<?php
// Array of available fruits
$fruits = array("lemons" => 1, "oranges" => 4, "bananas" => 5, "apples" => 10);

$fruitsArrayObject = new ArrayObject($fruits);
$fruitsArrayObject['pears'] = 4;

// create a copy of the array
$copy = $fruitsArrayObject->getArrayCopy();
print_r($copy);

?>

https://www.php.net/manual/en/arrayobject.getarraycopy.php থেকে



0

পিএইচপি অ্যারেতে, আপনাকে এই অ্যারের অনুলিপি পেতে কেবলমাত্র অন্যান্য ভেরিয়েবলের কাছে তাদের নিয়োগ করতে হবে। তবে প্রথমে আপনাকে এটি টাইপ সম্পর্কে নিশ্চিত করতে হবে, এটি অ্যারে বা অ্যারেঅবজেক্ট বা স্ট্ডবজেক্ট কিনা।

সাধারণ পিএইচপি অ্যারের জন্য:

$a = array(
'data' => 10
);

$b = $a;

var_dump($b);

output:

array:1 [
  "data" => 10
]


0

$arr_one_copy = array_combine(array_keys($arr_one), $arr_one);

শুধু আরও একটি সমাধান পোস্ট করতে;)


-1
foreach($a as $key => $val) $b[$key] = $val ;

কী এবং মান উভয়ই সংরক্ষণ করে। অ্যারে 'এ' অ্যারে 'বি' এর সঠিক কপি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.