কীভাবে আমি কোনও বস্তুর অযোগ্য (সংক্ষিপ্ত) শ্রেণীর নাম পেতে পারি?


153

আমি সম্পূর্ণ নেমস্পিড ক্লাসটি নির্দিষ্ট না করে কীভাবে পিএইচপি নামের স্পেসড এনভায়রনমেন্টের মধ্যে কোনও অবজেক্টের ক্লাস চেক করব।

উদাহরণস্বরূপ ধরুন আমার একটি অবজেক্ট লাইব্রেরি / সত্তা / চুক্তি / নাম ছিল।

Get_class পুরো নেমস্পিড ক্লাসটি দেয় কারণ নিম্নলিখিত কোডটি কাজ করে না।

If(get_class($object) == 'Name') {
... do this ...
}

নেমস্পেস ম্যাজিক কীওয়ার্ডটি বর্তমান নামস্থানটি প্রদান করে, যা পরীক্ষিত অবজেক্টের আরেকটি নেমস্পেস থাকলে কোনও ব্যবহার হয় না।

আমি কেবলমাত্র নেমস্পেসের সাথে পুরো ক্লাসের নামটি নির্দিষ্ট করতে পারি, তবে এটি কোডের কাঠামোটিতে লক করে দেখাবে। এছাড়াও আমি নামের স্থানটি পরিবর্তনশীল করতে চাইলে খুব বেশি ব্যবহারের প্রয়োজন নেই।

যে কেউ এটি করার একটি দক্ষ উপায় সম্পর্কে ভাবতে পারে। আমার ধারণা একটি বিকল্প হ'ল রেজেেক্স x


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

আমি একটি মোবাইল ডিভাইসে আছি, সুতরাং আমি একটি উপযুক্ত উত্তর জমা দিতে পারছি না, তবে সমাধানটি প্রতিফলন, বিশেষত প্রতিবিম্বক্লাস :: getShortName - php.net/manual/en/reflectionclass.getshortname.php
একাকী দিন

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

উত্তর:


182

আপনি প্রতিচ্ছবি দিয়ে এটি করতে পারেন। বিশেষত, আপনি ReflectionClass::getShortNameপদ্ধতিটি ব্যবহার করতে পারেন , যা শ্রেণীর নামটি স্থান ছাড়াই পেয়ে যায়।

প্রথমে আপনাকে একটি ReflectionClassদৃষ্টান্ত তৈরি করতে হবে এবং তারপরে getShortNameসেই উদাহরণটির পদ্ধতিটি কল করুন :

$reflect = new ReflectionClass($object);
if ($reflect->getShortName() === 'Name') {
    // do this
}

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


1
@ গ্রেগ.ফোর্বস কারণ Tenantবর্তমান নামদানে উপস্থিত নেই। var_dump($tenant instanceof \Library\Entity\People\Tenant)পরিবর্তে চেষ্টা করুন। এছাড়াও, কীভাবে useঅপারেটরটি ব্যবহার করবেন এবং পিএইচপি নামস্থানগুলির পিছনে সাধারণ ধারণাটি অনুসন্ধান করুন!
একাকী দিন

3
আমাকে এর আগে $reflect = new \ReflectionClass($object);
এইভাবে

7
আমি আমার অ্যাপ্লিকেশনগুলিতে সাধারণত প্রচুর পরিমাণে রিফ্লেকশন ক্লাস ভুডো করতে পছন্দ করি না কারণ এটি যদি অপ্রত্যাশিত ফলাফলগুলি ব্যবহার করে (সুরক্ষিত পদ্ধতিগুলি জনসাধারণ্যে পরিণত হওয়া ইত্যাদি) হয় তবে এটি অপ্রত্যাশিত ফলাফলের দিকে নিয়ে যেতে পারে। পরিবর্তে আপনি পিএইচপি যাদু ধ্রুবক উপর সহজ স্ট্রিং রিপ্লেসমেন্ট ব্যবহার করতে পারেন: str_replace(__NAMESPACE__ . '\\', '', __CLASS__);। এটি আরও দ্রুত, পারফরম্যান্স ভিত্তিক।
ফ্রাঙ্কলিন পি স্ট্রুব

2
পছন্দ করুন আমি সম্মত হই যে প্রতিবিম্বের ব্যবহারের অর্থ সাধারণত আপনি ভুল করছেন।
একাকী দিন

1
অনেক লোক সদস্যের দৃশ্যমানতার ওভাররাইডগুলির জন্য প্রতিচ্ছবি ব্যবহার করে যা বিএডি। এটা করো না! তবে উল্লেখ করে যে সাধারণভাবে প্রতিচ্ছবিগুলির ব্যবহার হ'ল ভুডু এবং এটি করা ভুল করে মানুষকে ভুল ধারণা দেয়। আপনার এগুলি এড়ানো উচিত নয়, আপনার সেগুলি বুঝতে হবে এবং কখন তারা উপকারী এবং কোন বিমূর্ততার স্তরে তা জেনে রাখা উচিত।
ভানজা ডি

131

(new \ReflectionClass($obj))->getShortName(); পারফরম্যান্সের সাথে সম্মত সঙ্গে সেরা সমাধান।

আমি কৌতূহল ছিলাম যে প্রদত্ত সমাধানগুলির মধ্যে কোনটি দ্রুততম, তাই আমি একসাথে একটি পরীক্ষা চালিয়েছি।

ফলাফল

Reflection: 1.967512512207 s ClassA
Basename:   2.6840535163879 s ClassA
Explode:    2.6507515668869 s ClassA

কোড

namespace foo\bar\baz;

class ClassA{
    public function getClassExplode(){
        return explode('\\', static::class)[0];
    }

    public function getClassReflection(){
        return (new \ReflectionClass($this))->getShortName();
    }

    public function getClassBasename(){
        return basename(str_replace('\\', '/', static::class));
    }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
);

for($r = 0; $r < $rounds; $r++){

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassReflection();
    }
    $end = microtime(true);
    $res["Reflection"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassBasename();
    }
    $end = microtime(true);
    $res["Basename"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassExplode();
    }
    $end = microtime(true);
    $res["Explode"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";

ফলাফলগুলি আমাকে অবাক করে দিয়েছে। আমি ভেবেছিলাম বিস্ফোরিত সমাধানটি দ্রুততম পথ হবে ...


1
দুর্দান্ত উত্তর। আমি খুব একই কোডটি চালাচ্ছিলাম তবে আমি আলাদা ফলাফল পেয়েছি (ম্যাকবুক প্রো আই 7, 16 জিবি র‌্যাম)। প্রতিবিম্ব: 0.382, বেসনাম: 0.380, বিস্ফোরিত: 0.399। আমি মনে করি এটি আপনার সিস্টেমে সবচেয়ে ভাল কিসের উপর নির্ভর করে ...
টোবিয়াস নহলম

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

6
আমি অবাক হয়েছি যে আপনার পরীক্ষায় ক্লাস এ এর ​​ছোট অবজেক্টের চেয়ে আরও বেশি বড় অবজেক্টের উপর রিফ্লেকশন ক্লাস ইনস্ট্যান্ট করার সময় এই টেস্টটি কি সত্য হবে ...
জো গ্রিন

2
100000 এর পরিবর্তে কেবলমাত্র একটি পুনরাবৃত্তি চালানো একটি ভিন্ন ফলাফল দেয়: প্রতিবিম্ব: 1.0967254638672 100000 তম / শ্রেণীর ক্লাসএ বেসনাম: 0.81062316894531 100000 তম / শ্রেণীর শ্রেণিবদ্ধ বিস্ফোরিত: 0.50067901611328 100000 তম / সে ক্লাসএ
এমসিআরফারফি

1
বিস্ফোরণ ('\\', স্ট্যাটিক :: শ্রেণি) [0]? এটি কি নেমস্পেসের প্রথম অংশটি ফেরত দেয় না? শেষ অংশটি ফিরে আসা উচিত, প্রথম নয়
2oppin

86

আমি https://stackoverflow.com/a/25472778/2386943 পরীক্ষায় সাবস্ট্রাস্ট যুক্ত করেছি এবং এটিই আমি দ্রুততম উপায় পরীক্ষা করতে পেরেছি (CentOS পিএইচপি 5.3.3, উবুন্টু পিএইচপি 5.5.9) উভয়ই আই 5 দিয়ে।

$classNameWithNamespace=get_class($this);
return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);

ফলাফল

Reflection: 0.068084406852722 s ClassA
Basename: 0.12301609516144 s ClassA
Explode: 0.14073524475098 s ClassA
Substring: 0.059865570068359 s ClassA 

কোড

namespace foo\bar\baz;
class ClassA{
  public function getClassExplode(){
    $c = array_pop(explode('\\', get_class($this)));
    return $c;
  }

  public function getClassReflection(){
    $c = (new \ReflectionClass($this))->getShortName();
    return $c;
  }

  public function getClassBasename(){
    $c = basename(str_replace('\\', '/', get_class($this)));
    return $c;
  }

  public function getClassSubstring(){
    $classNameWithNamespace = get_class($this);
    return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);
  }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
    "Substring" => array()
);

for($r = 0; $r < $rounds; $r++){

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassReflection();
  }
  $end = microtime(true);
  $res["Reflection"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassBasename();
  }
  $end = microtime(true);
  $res["Basename"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassExplode();
  }
  $end = microtime(true);
  $res["Explode"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassSubstring();
  }
  $end = microtime(true);
  $res["Substring"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";
echo "Substring: ".array_sum($res["Substring"])/count($res["Substring"])." s ".$a->getClassSubstring()."\n";

== আপডেট ==

@ মিঃব্যান্ডারসনচের মন্তব্যে যেমন উল্লেখ করা হয়েছে এটি করার আরও দ্রুততর উপায়ও রয়েছে:

return substr(strrchr(get_class($this), '\\'), 1);

"SubstringStrChr" (প্রায় 0.001 s পর্যন্ত সংরক্ষণ করা) সহ আপডেট হওয়া পরীক্ষার ফলাফলগুলি এখানে:

Reflection: 0.073065280914307 s ClassA
Basename: 0.12585079669952 s ClassA
Explode: 0.14593172073364 s ClassA
Substring: 0.060415267944336 s ClassA
SubstringStrChr: 0.059880912303925 s ClassA

5
কেবলমাত্র আমরা দক্ষতার জন্য তালিকাবদ্ধ করেছিলাম কারণ এই সমাধানটিতে সরবরাহ করা পরীক্ষার তুলনায় এটিকে আমি দ্রুততম হিসাবে খুঁজে পেয়েছি সাবস্ট্রাস্টার (স্ট্রিচক্র (get_class ($ اعتراض), '\\'), 1); প্রতিবিম্ব: 0.084223914146423 s ক্লাসএ - বেসনাম: 0.13206427097321 s ক্লাসএ - বিস্ফোরিত: 0.15331919193268 s ক্লাসা - সাবস্ট্রিং: 0.068068099021912 s ক্লাসা - স্ট্র্যাচার: 0.06472008228302 s ClassA -
ctatro85

আমি এই থ্রেডটি পেরিয়ে এসেছি এবং পরীক্ষার জন্য একটি অতিরিক্ত মানদণ্ড যুক্ত করেছি str_replace(__NAMESPACE__ . '\\', '', __CLASS__);। একটি দুর্বল ভার্চুয়াল মেশিনের ফলাফলগুলি এগুলির থেকে প্রায় দ্বিগুণ দ্রুত হতে দেখায়। php -f bench.php Reflection: 0.44037771224976 s ClassA Basename: 0.48089025020599 s ClassA Explode: 0.54955270290375 s ClassA Substring: 0.38200764656067 s ClassA Frank's Custom Benchmark: 0.22782742977142 s ClassA
ফ্র্যাঙ্কলিন পি স্ট্রুব

1
@ এমআরব্যান্ডারসনেচ আপনি সঠিক আছেন আমি আপনার সমাধানটি পরীক্ষা করেছি এবং এটি আমাকে প্রায় 0.001 সেভ করে। আমি আপনার সাথে আমার উত্তর আপডেট!
মাবিআই

3
সতর্কতা: এই কোডটি বিশ্বব্যাপী নেমস্পেসের ক্লাসগুলির সাথে কাজ করে না (যেমন: তাদের পুরো নামটি তাদের সংক্ষিপ্ত নামের সমান)! মত পরীক্ষা কিছু আমি উপদেশ: if ($pos = strrchr(static::class, '\\')) { .. } else { ... }
ত্রিস্তান জাহিয়ার

1
এটি বিশ্বব্যাপী নেমস্পেসেও কাজ করতে, $classNameShort = substr(strrchr('\\' . get_class($this), '\\'), 1);
ক্লাস নামটি

25

আপনি যদি লারাভেল পিএইচপি ফ্রেমওয়ার্ক ব্যবহার করছেন তবে এটি করার আরও সহজ উপায় এখানে:

<?php

// usage anywhere
// returns HelloWorld
$name = class_basename('Path\To\YourClass\HelloWorld');

// usage inside a class
// returns HelloWorld
$name = class_basename(__CLASS__);

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

6
আমার মনে হয় তিনি বলেছিলেন
স্কট

4
ধন্যবাদ, আমি লারাভেল ব্যবহার করছি এবং এই উত্তরটি আমার বেশ কয়েকটা সময় সাশ্রয় করেছে।
জেরেমি ওয়াদামস


18

আমি এটি ব্যবহার:

basename(str_replace('\\', '/', get_class($object)));

আপনিও চেষ্টা করতে পারেন: $ className = বিস্ফোরণ ('\\', বেসনাম (get_class ($ এটি))); $ className = অ্যারে_পপ ($ শ্রেণীর নাম); সরল শ্রেণীর নাম পেতে। অথবা সাবস্ট্রটার ব্যবহার করুন।
dompie

13
উইন্ডোজ শুধুমাত্র উইন্ডোজে কাজ করে, স্ল্যাশ (/) এবং ব্যাকস্ল্যাশ () উভয়ই ডিরেক্টরি বিভাজক চরিত্র হিসাবে ব্যবহৃত হয়। অন্যান্য পরিবেশে এটি ফরোয়ার্ড স্ল্যাশ (/) php.net/manual/en/function.basename.php
ওজাইচেক

আমি এখন এটি স্থির করেছি। ধন্যবাদ, @ ওজিচেক
থিওডোর আর স্মিথ

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

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

16

ওয়ান-লাইনার হিসাবে সংক্ষিপ্ত নামটি পেতে ( পিএইচপি 5.4 থেকে ):

echo (new ReflectionClass($obj))->getShortName();

এটি একটি পরিষ্কার পদ্ধতির এবং যুক্তিসঙ্গত দ্রুত


1
আমি আশ্চর্য হয়েছি কীভাবে এটি বেঞ্চমার্কগুলিতে স্ট্রিং নিষ্কাশনটির সাথে তুলনা করে। মনে হচ্ছে এটি অনেক ধীর হবে।
যাচাই করা হয়নি যোগাযোগ

12

আমি নিজেকে এমন এক অনন্য পরিস্থিতিতে পেয়েছি যেখানে instanceofব্যবহার করা যায় না (বিশেষত নাম স্পিডের বৈশিষ্ট্য) এবং আমার পক্ষে খুব দক্ষতার সাথে সংক্ষিপ্ত নামটির প্রয়োজন ছিল তাই আমি আমার নিজের একটি সামান্য বেঞ্চমার্ক করেছি। এটি এই প্রশ্নের উত্তর থেকে সমস্ত বিভিন্ন পদ্ধতি এবং তারতম্য অন্তর্ভুক্ত।

$bench = new \xori\Benchmark(1000, 1000);     # https://github.com/Xorifelse/php-benchmark-closure
$shell = new \my\fancy\namespace\classname(); # Just an empty class named `classname` defined in the `\my\fancy\namespace\` namespace

$bench->register('strrpos', (function(){
    return substr(static::class, strrpos(static::class, '\\') + 1);
})->bindTo($shell));

$bench->register('safe strrpos', (function(){
    return substr(static::class, ($p = strrpos(static::class, '\\')) !== false ? $p + 1 : 0);
})->bindTo($shell));

$bench->register('strrchr', (function(){
    return substr(strrchr(static::class, '\\'), 1);
})->bindTo($shell));

$bench->register('reflection', (function(){
    return (new \ReflectionClass($this))->getShortName();
})->bindTo($shell));

$bench->register('reflection 2', (function($obj){
    return $obj->getShortName();
})->bindTo($shell), new \ReflectionClass($shell));

$bench->register('basename', (function(){
    return basename(str_replace('\\', '/', static::class));
})->bindTo($shell));

$bench->register('explode', (function(){
    $e = explode("\\", static::class);
    return end($e);
})->bindTo($shell));

$bench->register('slice', (function(){
    return join('',array_slice(explode('\\', static::class), -1));
})->bindTo($shell));    

print_r($bench->start());

পুরো ফলাফলের একটি তালিকা এখানে রয়েছে তবে এখানে হাইলাইটগুলি রয়েছে:

  • আপনি যদি যাইহোক প্রতিবিম্ব ব্যবহার করতে যাচ্ছেন তবে ব্যবহার করা $obj->getShortName()হ'ল দ্রুততম পদ্ধতি ; শুধুমাত্র প্রতিবিম্ব ব্যবহার করে সংক্ষিপ্ত নাম পাওয়ার জন্য করে এটি প্রায় ধীরতম পদ্ধতি।
  • 'strrpos'যদি কোনও অজানা নামস্থানে না থাকে তবে ভুল মানটি ফিরিয়ে দিতে পারে তবে 'safe strrpos'সামান্য ধীর হলেও আমি বলব যে এটিই বিজয়ী।
  • 'basename'লিনাক্স এবং উইন্ডোজের মধ্যে সামঞ্জস্যপূর্ণ করতে আপনাকে ব্যবহার করতে হবে str_replace()যা এই পদ্ধতিটিকে তাদের সবচেয়ে ধীর করে তোলে।

ফলাফলের সরলীকৃত ছক, গতি সবচেয়ে ধীর পদ্ধতির তুলনায় পরিমাপ করা হয়:

+-----------------+--------+
| registered name | speed  |
+-----------------+--------+
| reflection 2    | 70.75% |
| strrpos         | 60.38% |
| safe strrpos    | 57.69% |
| strrchr         | 54.88% |
| explode         | 46.60% |
| slice           | 37.02% |
| reflection      | 16.75% |
| basename        | 0.00%  |
+-----------------+--------+

8

আপনি explodeनेमস্পেস আলাদা endকরার জন্য এবং শ্রেণীর নাম পাওয়ার জন্য ব্যবহার করতে পারেন :

$ex = explode("\\", get_class($object));
$className = end($ex);

7

Yii উপায়

\yii\helpers\StringHelper::basename(get_class($model));

ইআইআইআই জিআই কোড জেনারেটরে এই পদ্ধতিটি ব্যবহার করে

পদ্ধতি ডকুমেন্টেশন

এই পদ্ধতিটি পিএইচপি ফাংশন বেসনামের সাথে সমান () বাদে এটি অপারেটিং সিস্টেমের চেয়ে পৃথক directory এবং / ডিরেক্টরি বিভাজক উভয় হিসাবে বিবেচনা করবে। এই পদ্ধতিটি মূলত পিএইচপি নেমস্পেসে কাজ করার জন্য তৈরি করা হয়েছিল। আসল ফাইল পাথ নিয়ে কাজ করার সময়, পিএইচপি এর বেসনাম () আপনার পক্ষে ভাল কাজ করা উচিত। দ্রষ্টব্য: এই পদ্ধতিটি প্রকৃত ফাইল সিস্টেম, বা ".." এর মতো পথের উপাদানগুলির সম্পর্কে অবগত নয়।

অধিক তথ্য:

https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseStringHelper.php http://www.yiiframework.com/doc-2.0/yii-helpers-basestringhelper.html#basename()-detail


স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম। আপনার উত্তরের জন্য আরও তথ্য সরবরাহ করুন। এটি কী করে এবং কীভাবে এটি ব্যবহার করতে পারে।
জেনস 21

1
এটি আমার জন্য উইন্ডোতে কাজ করেছে তবে লিনাক্সে নয়, কারণ সম্ভবত নেমস্পেসগুলি উইন্ডোজ ডিরেক্টরিগুলির ব্যাকস্ল্যাশ '\' আকারে রয়েছে, অন্যদিকে লিনাক্স বেসনামটি ডিরেক্টরি বিভাজককে ফরোয়ার্ড স্ল্যাশ '/' হিসাবে বিবেচনা করে। সুতরাং আমি এটি strtr সঙ্গে প্রায় কাজ। ' বেসনাম (স্ট্র্ট ($ শ্রেণি, '\\', '/'))
FantomX1

6

এখানে পিএইচপি 5.4+ এর সহজ সমাধান

namespace {
    trait Names {
        public static function getNamespace() {
            return implode('\\', array_slice(explode('\\', get_called_class()), 0, -1));
        }

        public static function getBaseClassName() {
            return basename(str_replace('\\', '/', get_called_class()));
        }
    }
}

ফিরবে কী?

namespace x\y\z {
    class SomeClass {
        use \Names;
    }

    echo \x\y\z\SomeClass::getNamespace() . PHP_EOL; // x\y\z
    echo \x\y\z\SomeClass::getBaseClassName() . PHP_EOL; // SomeClass
}

বর্ধিত শ্রেণীর নাম এবং নেমস্পেস এতে ভাল কাজ করে:

namespace d\e\f {

    class DifferentClass extends \x\y\z\SomeClass {

    }

    echo \d\e\f\DifferentClass::getNamespace() . PHP_EOL; // d\e\f
    echo \d\e\f\DifferentClass::getBaseClassName() . PHP_EOL; // DifferentClass
}

বিশ্বব্যাপী নেমস্পেসে শ্রেণীর কী হবে?

namespace {

    class ClassWithoutNamespace {
        use \Names;
    }

    echo ClassWithoutNamespace::getNamespace() . PHP_EOL; // empty string
    echo ClassWithoutNamespace::getBaseClassName() . PHP_EOL; // ClassWithoutNamespace
}

3

আপনার যদি ক্লাসের নামটি ক্লাসের ভিতরে থেকে ডেকে নেওয়া এবং নাম স্থানটি না জানতে চান তবে আপনি এটিটি ব্যবহার করতে পারেন

$calledClass = get_called_class();
$name = strpos($calledClass, '\\') === false ?
    $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

আপনার ক্লাসের অভ্যন্তরে এমন কোনও পদ্ধতি থাকে যা অন্যান্য ক্লাস দ্বারা প্রসারিত হয় This তদতিরিক্ত, যদি নেমস্পেসগুলি একেবারে ব্যবহার না করা হয় তবে এটি কাজ করে।

উদাহরণ:

<?php
namespace One\Two {
    class foo
    {
        public function foo()
        {
            $calledClass = get_called_class();
            $name = strpos($calledClass, '\\') === false ?
                $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

            var_dump($name);
        }
    }
}

namespace Three {
    class bar extends \One\Two\foo
    {
        public function bar()
        {
            $this->foo();
        }
    }
}

namespace {
    (new One\Two\foo)->foo();
    (new Three\bar)->bar();
}

// test.php:11:string 'foo' (length=3)
// test.php:11:string 'bar' (length=3)

2

@ মাবি'র উত্তরের ভিত্তিতে আমি এটি তৈরি করেছি:

trait ClassShortNameTrait
{
    public static function getClassShortName()
    {
        if ($pos = strrchr(static::class, '\\')) {
            return substr($pos, 1);
        } else {
            return static::class;
        }
    }
}

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

namespace Foo\Bar\Baz;

class A
{
    use ClassShortNameTrait;
}

A::classফিরে আসে Foo\Bar\Baz\A, কিন্তু A::getClassShortName()ফিরে আসে A

পিএইচপি> = 5.5 এর জন্য কাজ করে।


2

আমি জানি এটি একটি পুরানো পোস্ট তবে আমি এটিই ব্যবহার করি - উপরের পোস্টের চেয়ে দ্রুততম এই পদ্ধতিটি আপনার ক্লাস থেকে কল করুন, প্রতিবিম্বটি ব্যবহার করার চেয়ে অনেক দ্রুত

namespace Foo\Bar\Baz;

class Test {
    public function getClass() {
        return str_replace(__NAMESPACE__.'\\', '', static::class);
    }
}

দুর্ভাগ্যক্রমে এটি কেবল তখনই কাজ করে যদি আপনি ক্লাসে যার নামটি কল করতে চান, কেবল কোনও স্ট্রিং হিসাবে কোনও শ্রেণির নাম নয়।
জুরচিক্স ২৩

1

Get_class এর ডকুমেন্টেশন পৃষ্ঠায় পাওয়া গেছে , যেখানে এটি আমার দ্বারা পোস্ট করা হয়েছে এনভিটিং ডট কম

function get_class_name($object = null)
{
    if (!is_object($object) && !is_string($object)) {
        return false;
    }

    $class = explode('\\', (is_string($object) ? $object : get_class($object)));
    return $class[count($class) - 1];
}

তবে নেমস্পেসগুলির ধারণাটি আপনার কোডটি গঠন করা। এর অর্থ হ'ল একাধিক নেমস্পেসে আপনার একই নামের ক্লাস থাকতে পারে। তাত্ত্বিকভাবে, আপনি যে বস্তুটি পাস করবেন তার নাম (স্ট্রিপড) শ্রেণি নাম থাকতে পারে, যদিও এখনও আপনি প্রত্যাশার চেয়ে একেবারে পৃথক অবজেক্ট being

তদ্ব্যতীত, আপনি একটি নির্দিষ্ট বেস শ্রেণীর জন্য চেক করতে চাইতে পারেন , এই ক্ষেত্রে get_classকৌশলটি মোটেই না করে। আপনি অপারেটরটি পরীক্ষা করতে চাইতে পারেন instanceof


1

ক্লাসের নাম স্থান না থাকলে আপনি অপ্রত্যাশিত ফলাফল পেতে পারেন। অর্থাত্ get_classফিরে Foo, তারপর $baseClassহবে oo

$baseClass = substr(strrchr(get_class($this), '\\'), 1);

এটি সহজেই get_classব্যাকস্ল্যাশ সহ উপসর্গ দ্বারা স্থির করা যেতে পারে :

$baseClass = substr(strrchr('\\'.get_class($this), '\\'), 1);

এখন নেমস্পেসবিহীন ক্লাসগুলিও সঠিক মান প্রদান করবে।


1

পূর্ববর্তী দেখানো পদ্ধতিগুলির চেয়ে বেশিরভাগ ভাল পুরাতন রেজেক্স দ্রুততর বলে মনে হচ্ছে:

// both of the below calls will output: ShortClassName

echo preg_replace('/.*\\\\/', '', 'ShortClassName');
echo preg_replace('/.*\\\\/', '', 'SomeNamespace\SomePath\ShortClassName');

সুতরাং আপনি যখন একটি সংক্ষিপ্ত শ্রেণীর নাম বা সম্পূর্ণরূপে যোগ্যতাসম্পন্ন (ক্যানোনিকাল) শ্রেণীর নাম সরবরাহ করেন তখনও এটি কাজ করে।

রেজেক্স কী করে তা হ'ল এটি শেষের বিভাজকটি না পাওয়া পর্যন্ত পূর্ববর্তী সমস্ত অক্ষর গ্রাস করে (যা গ্রাসও করা হয়)। সুতরাং বাকী স্ট্রিংটি স্বল্প শ্রেণীর নাম হবে।

আপনি যদি কোনও আলাদা বিভাজক (যেমন। /) ব্যবহার করতে চান তবে তার পরিবর্তে কেবল সেই বিভাজকটি ব্যবহার করুন। ব্যাকস্ল্যাশ (যেমন। \) এবং ইনপুট প্যাটার্নে প্যাটার্ন চর (যেমন। /) এড়াতে ভুলবেন না।


1

"রিফ্লেকশনক্লাস" সংস্করণ নির্ভর হতে পারে কেবল অনুসরণটি ব্যবহার করুন:

if(class_basename(get_class($object)) == 'Name') {
... do this ...
}

বা এমনকি পরিষ্কার

if(class_basename(ClassName::class) == 'ClassName') {
... do this ...
}

0

পিএইচপি.এন.কে উদ্ধৃত করে:

উইন্ডোজে, উভয় স্ল্যাশ (/) এবং ব্যাকস্ল্যাশ () ডিরেক্টরি বিভাজক চরিত্র হিসাবে ব্যবহৃত হয়। অন্যান্য পরিবেশে এটি ফরোয়ার্ড স্ল্যাশ (/)।

এই তথ্যের ভিত্তিতে এবং আরজজেন উত্তর থেকে প্রসারিত হওয়াতে এটি উইন্ডোজ এবং নিক্স * উভয় সিস্টেমে কাজ করা উচিত:

<?php

if (basename(str_replace('\\', '/', get_class($object))) == 'Name') {
    // ... do this ...
}

দ্রষ্টব্য: আমি এর ReflectionClassবিরুদ্ধে একটি প্রতিদ্বন্দ্বিতা করেছি basename+str_replace+get_classএবং প্রতিবিম্বটি ব্যবহার করে বেসনেম পদ্ধতির ব্যবহারের চেয়ে প্রায় 20% দ্রুত, তবে ওয়াইএমএমভি।


0

যে কোনও পরিবেশে কাজ করা দ্রুত এবং imho সবচেয়ে সহজ সমাধান:

<?php

namespace \My\Awesome\Namespace;

class Foo {

  private $shortName;

  public function fastShortName() {
    if ($this->shortName === null) {
      $this->shortName = explode("\\", static::class);
      $this->shortName = end($this->shortName);
    }
    return $this->shortName;
  }

  public function shortName() {
    return basename(strtr(static::class, "\\", "/"));
  }

}

echo (new Foo())->shortName(); // "Foo"

?>

1
এই কারণেই আমি পিএইচপি অভ্যন্তরীণ শ্রেণীর তথ্য অপারেটরদের থাকতে চাই। $Object->__class->getShortName()পিএইচপি সম্পর্কে সত্যিই আমাকে বিস্মিত করার মতো সহজ হওয়া উচিত যা করার জন্য একটি বাহ্যিক প্রতিফলককে ইনস্ট্যান্ট করা । আপনার পদ্ধতির কাজ করে, তবে এখন আপনি ভাষা ক্লাসটি কী হবে তা প্রকাশ করার জন্য আপনার ক্লাসে কংক্রিটের পদ্ধতি রাখছেন।
এগ্মলঞ্চার

"কংক্রিট" ছাড়াই পিএইচপি (বা আমরা তাদের প্রক্রিয়াজাতকরণ বলি) ফাংশন অসম্ভব। আসুন পিএইচপি 6 এর জন্য অপেক্ষা করুন (ভাল, যদি এটি কখনও আসে)।
ফ্লেশগ্রিন্ডার


0

যদি আপনি কেবল নামের স্থান ফাঁকা করে থাকেন এবং সর্বশেষের পরে কিছু চান name নেমস্পেসের সাথে ক্লাসের নামে (অথবা '\' না থাকলে কেবল নাম) আপনি এই জাতীয় কিছু করতে পারেন:

$base_class = preg_replace('/^([\w\\\\]+\\\\)?([^\\\\]+)$/', '$2', get_class($myobject));

মূলত এটি অক্ষর বা ব্যাকস্ল্যাশগুলির কোনও সংমিশ্রণ পাওয়া এবং শেষ ব্যাকস্ল্যাশ পর্যন্ত কেবল নন-ব্যাকস্ল্যাশ অক্ষর এবং স্ট্রিংয়ের শেষ অবধি প্রত্যাবর্তন করা অবধি re যোগ করা? প্রথম গোষ্ঠীকরণের অর্থ প্যাটার্ন মিলটি না থাকলে এটি পুরো স্ট্রিংটি ফিরিয়ে দেয়।


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