পিএইচপিতে কোনও চলক থেকে কোনও শ্রেণি ইনস্ট্যান্ট করবেন?


146

আমি জানি এই প্রশ্নটি বরং অস্পষ্ট মনে হচ্ছে তাই আমি এটি একটি উদাহরণ দিয়ে আরও স্পষ্ট করে তুলব:

$var = 'bar';
$bar = new {$var}Class('var for __construct()'); //$bar = new barClass('var for __construct()');

এটাই আমি করতে চাই। তুমি এটা কি ভাবে করবে? আমি অবশ্যই এইভাবে ইওল () ব্যবহার করতে পারি:

$var = 'bar';
eval('$bar = new '.$var.'Class(\'var for __construct()\');');

তবে আমি বরং এভাল () থেকে দূরে থাকি। এটি ছাড়াই কি উপায় আছে ()?

উত্তর:


213

প্রথমে শ্রেণীর নামটি একটি ভেরিয়েবলের মধ্যে রাখুন:

$classname=$var.'Class';

$bar=new $classname("xyz");

এটি প্রায়শই এমন ধরণের জিনিস যা আপনি কারখানার প্যাটার্নে আবৃত দেখতে পাবেন।

দেখুন নামস্থান এবং গতিশীল ভাষা বৈশিষ্ট্য আরও বিস্তারিত জানার জন্য।


2
এইভাবেই আমি এটি করি। নোট করুন যে ক্লাসের মধ্যে থেকে আপনি পিতামাতা এবং স্ব ব্যবহার করতে পারেন।
রস

1
অনুরূপ নোটে, আপনি $ var = 'নাম'ও করতে পারেন; obj $ -> { 'get' $ Var।} ();
মারিও

1
ভাল কথা, যদিও এটি কেবল পদ্ধতি কলগুলির জন্য কাজ করে এবং নির্মাণকারীদের জন্য নয়
পল ডিকসন

12
: আপনি নামস্থান সঙ্গে কাজ করেন, তাহলে বর্তমান নামস্থান স্ট্রিং পুরা$var = __NAMESPACE__ . '\\' . $var . 'Class';
bastey

@ বাসে - তবে কেন? আমি স্রেফ বের করার জন্য খুব বেশি সময় ব্যয় করেছি, কেন এটি শ্রেণীর নামের পূর্ববর্তী নেমস্পেস ছাড়া কাজ করবে না ...
jkulak

72

আপনি যদি নেমস্পেস ব্যবহার করেন

আমার নিজের অনুসন্ধানে, আমি আপনাকে উল্লেখ করতে ভাল বলে মনে করি যে আপনি (যতদূর আমি বলতে পারি) অবশ্যই একটি শ্রেণীর পুরো নেমস্পেসের পথটি ঘোষণা করতে হবে।

MyClass.php

namespace com\company\lib;
class MyClass {
}

index.php

namespace com\company\lib;

//Works fine
$i = new MyClass();

$cname = 'MyClass';

//Errors
//$i = new $cname;

//Works fine
$cname = "com\\company\\lib\\".$cname;
$i = new $cname;

6
নেমস্পেসের সাথে তৈরি করার প্রয়োজন হলে কেবলমাত্র কার্যকর সমাধান আপনার হয়। শেয়ার করার জন্য ধন্যবাদ!
টিয়াগো গাউভা

তবে এটি কেবল অদ্ভুত, কেন এটি ঘোষিত নেমস্পেস ব্যবহার করবে না?
ইস্রায়েল ডভ

@ ইস্রায়েলডভ হ্যাঁ এটি অবশ্যই স্বজ্ঞাতরোধী। তবে যে কোনও কারণে এটি এই প্রসঙ্গে অদ্ভুত আচরণ করে। ধন্যবাদ পিএইচপি
csga5000

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

61

ডায়নামিক কনস্ট্রাক্টর পরামিতিগুলি কীভাবে পাস করতে হয়

আপনি যদি ক্লাসে ডায়নামিক কনস্ট্রাক্টর পরামিতিগুলি পাস করতে চান তবে আপনি এই কোডটি ব্যবহার করতে পারেন:

$reflectionClass = new ReflectionClass($className);

$module = $reflectionClass->newInstanceArgs($arrayOfConstructorParameters);

গতিশীল ক্লাস এবং পরামিতি সম্পর্কে আরও তথ্য

পিএইচপি> = 5.6

পিএইচপি 5.6 হিসাবে আপনি আর্গুমেন্ট আনপ্যাকিং ব্যবহার করে এটি আরও সহজ করতে পারেন :

// The "..." is part of the language and indicates an argument array to unpack.
$module = new $className(...$arrayOfConstructorParameters);

এটি নির্দেশ করার জন্য অসন্তুষ্ট গোটকে ধন্যবাদ।


7
পিএইচপি 5.6 থেকে আপনার পক্ষে যুক্তি আনপ্যাকিং ব্যবহার করতে সক্ষম হওয়া উচিত:new $className(...$params)
অসন্তুষ্টগীত

29
class Test {
    public function yo() {
        return 'yoes';
    }
}

$var = 'Test';

$obj = new $var();
echo $obj->yo(); //yoes

না, একটি ভাল উদাহরণ না। সবকিছু যদি একই পিএইচপি ফাইলে থাকে তবে কেবলমাত্র কাজ করে।
fralbo

2
২ য় জিএবি এই মন্তব্যটি সরানো উচিত। এই প্রশ্নের সাথে অটোলয়েডিংয়ের কোনও সম্পর্ক নেই।
জিম মাগুয়ের

-1

আমি call_user_func()বা call_user_func_arrayপিএইচপি পদ্ধতিগুলি সুপারিশ করব । আপনি এগুলি এখানে পরীক্ষা করতে পারেন ( কল_উজার_ফানস_আরে , কল_উজার_ফঙ্ক )।

উদাহরণ

class Foo {
static public function test() {
    print "Hello world!\n";
}
}

 call_user_func('Foo::test');//FOO is the class, test is the method both separated by ::
 //or
 call_user_func(array('Foo', 'test'));//alternatively you can pass the class and method as an array

আপনার যদি যুক্তি থাকে আপনি পদ্ধতিটিতে যাচ্ছেন তবে call_user_func_array()ফাংশনটি ব্যবহার করুন ।

উদাহরণ।

class foo {
function bar($arg, $arg2) {
    echo __METHOD__, " got $arg and $arg2\n";
}
}

// Call the $foo->bar() method with 2 arguments
call_user_func_array(array("foo", "bar"), array("three", "four"));
//or
//FOO is the class, bar is the method both separated by ::
call_user_func_array("foo::bar"), array("three", "four"));

3
এই উত্তরটি প্রশ্নের ক্ষেত্রে প্রযোজ্য নয়। ওপি জিজ্ঞাসা করছে যে কীভাবে একটি চলক স্ট্রিং থেকে কোনও শ্রেণি স্থাপন করতে (শ্রেণি __ কনস্ট্রাক্ট পদ্ধতিটি গতিশীলভাবে ট্রিগার করা) এবং CLASS OBJECT কে একটি নতুন ভেরিয়েবলের মধ্যে ফিরিয়ে আনতে হবে - আপনার পরামর্শটি শ্রেণীর-> পদ্ধতিটির মান ([]] ফিরিয়ে দেবে আপনি ' পুনরায় কলিং, ক্লাস অবজেক্ট নয় তাই এই ক্ষেত্রে প্রযোজ্য না। ফিরতি মানটি দেখুন php.net/manual/en/function.call-user-func-array.php
ChrisN
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.