পিএইচপি-তে গতিশীলভাবে নির্বাচিত শ্রেণীর ধ্রুবকের মান পান


114

আমি এই জাতীয় কিছু করতে সক্ষম হতে চাই:

class ThingIDs
{
    const Something = 1;
    const AnotherThing = 2;
}

$thing = 'Something';
$id = ThingIDs::$thing;

এটি কাজ করে না। সমান কিছু করার সহজ সরল উপায় আছে কি? নোট করুন যে আমি ক্লাসের সাথে আটকে আছি; এটি একটি লাইব্রেরিতে আমি আবার লিখতে পারি না। আমি কোড লিখছি যা কমান্ড লাইনে আর্গুমেন্ট গ্রহণ করে, এবং আমি সত্যই এটি আইডি সংখ্যার পরিবর্তে প্রতীকী নামগুলি গ্রহণ করতে চাই।


আপনি চেষ্টা করতে পারেন ThingIDs::{$thing}?
ডেভিড রডরিগস

ইতিমধ্যে চেষ্টা করা হয়েছে। মারাত্মক রানটাইম ত্রুটির পরিবর্তে আমাকে পার্স ত্রুটি করে।
বেন

উত্তর:


182

$id = constant("ThingIDs::$thing");

http://php.net/manual/en/function.constant.php


1
পার্শ্ব নোট: আপনি যদি প্রথমে ধ্রুবকটি সংজ্ঞায়িত করা হয় কিনা তা যাচাই করতে চান, এটিdefined("ThingIDs::$thing");
প্যারিস ভার্নি

3
বা $ আইডি = ধ্রুব ("স্ব :: $ জিনিস");
লাইন

3
এর অনুরূপ,$id = constant(sprintf('%s::%s', ThingIDs::class, $thing));
ডেভিড বাউকুম

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

5
আপনার ব্যবহারের উপর নির্ভর করে, আমার সমাধান কম জটিল। বিশেষত আপনি যদি পিএসআর -4 অটোলয়েডিং ব্যবহার করছেন তবে আপনার কোডটি কুৎসিত হতে পারে এফকিউডিএন সর্বত্র বানান করা। ব্যবহার দ্বারা useফাইল উপরের এবং তারপর ব্যবহার ::classপদ্ধতি জাদুর FQDN পাঠযোগ্যতা উন্নতি জন্য।
ডেভিড বাউকুম

27

প্রতিবিম্ব ব্যবহার করুন

$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);

3
প্রতিচ্ছবিগুলি সত্যই ক্লাস, পদ্ধতি এবং আরও অনেক কিছু অন্তর্দৃষ্টি দেয় এবং দেখে মনে হয় যে অনেক লোক তাদের বুঝতে এটি পদক্ষেপ নিতে ভয় পান। দুর্দান্ত উত্তর।
মাইক ম্যাকিনটোস

2
@ মেকিম্যাকিনটোস আমি সেগুলি বোঝার পদক্ষেপ নিয়েছি তবে গ্রহণযোগ্য উত্তরের তুলনায় পারফরম্যান্স এফেক্টের দিক থেকে তেমন কিছু দেখিনি। এটি এমন কিছু যা আমি জানতে আগ্রহী। কোনও নতুন ক্লাস ইনস্ট্যান্ট করা মনে হচ্ছে স্ট্যাটিকভাবে কেবল ধ্রুবককে কল করার চেয়ে এটির চেয়ে আরও বড় পারফরম্যান্স হিট। এই সম্বন্ধে তোমার চিন্তা ভাবনা কি?
দুদেওয়াদ

13

আপনি যদি নেমস্পেস ব্যবহার করছেন তবে আপনার ক্লাসের সাথে নেমস্পেসটি অন্তর্ভুক্ত করা উচিত।

echo constant('My\Application\ThingClass::ThingConstant'); 

3
<?php

class Dude {
    const TEST = 'howdy';
}

function symbol_to_value($symbol, $class){
    $refl = new ReflectionClass($class);
    $enum = $refl->getConstants();
    return isset($enum[$symbol])?$enum[$symbol]:false;
}

// print 'howdy'
echo symbol_to_value('TEST', 'Dude');

3

সহায়ক ফাংশন

আপনি এর মতো একটি ফাংশন ব্যবহার করতে পারেন:

function class_constant($class, $constant)
{
    if ( ! is_string($class)) {
        $class = get_class($class);
    }

    return constant($class . '::' . $constant);
}

এটি দুটি যুক্তি লাগে:

  • শ্রেণীর নাম বা বস্তুর উদাহরণ
  • ক্লাস ধ্রুবক নাম

যদি কোনও অবজেক্ট উদাহরণটি পাস করা হয় তবে এর শ্রেণির নামটি অনুমান করা হয়। আপনি যদি পিএইচপি 7 ব্যবহার করেন তবে আপনি ::classনামের স্থানগুলি সম্পর্কে চিন্তা না করে উপযুক্ত শ্রেণির নাম পাস করতে ব্যবহার করতে পারেন ।

উদাহরণ

class MyClass
{
    const MY_CONSTANT = 'value';
}

class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)

$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'

0

আপনার যদি ক্লাসে নিজেই একটি রেফারেন্স থাকে তবে আপনি নিম্নলিখিতগুলি করতে পারেন:

if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
   // class constant is defined
}

0

আমার সমস্যা এই বিষয়টির সাথে সাদৃশ্যপূর্ণ ছিল। যখন আপনার অবজেক্ট থাকে তবে ক্লাসের নাম নয়, আপনি ব্যবহার করতে পারেন:

$class_name = get_class($class_object);
$class_const = 'My_Constant';

$constant_value = constant($class_name.'::'.$class_const);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.