অটোল্যাড সহ আমি কীভাবে পিএইচপি নেমস্পেস ব্যবহার করব?


104

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

মারাত্মক ত্রুটি: ক্লাস 'Class1' মধ্যে পাওয়া যায়নি /usr/local/www/apache22/data/public/php5.3/test.php উপর লাইন 10

কেউ আমাকে বলতে পারে যে আমি কী ভুল করছি?

আমার কোডটি এখানে:

Class1.php:

<?php

namespace Person\Barnes\David
{
    class Class1
    {
        public function __construct()
        {
            echo __CLASS__;
        }
    }
}

?>

test.php:

<?php

function __autoload($class)
{
    require $class . '.php';
}

use Person\Barnes\David;

$class = new Class1();

?>

উত্তর:


119

ক্লাস 1 বিশ্বব্যাপী সুযোগে নেই।

কাজের উদাহরণের জন্য নীচে দেখুন:

<?php

function __autoload($class)
{
    $parts = explode('\\', $class);
    require end($parts) . '.php';
}

use Person\Barnes\David as MyPerson;

$class = new MyPerson\Class1();

সম্পাদনা (২০০৯-১২-১৪):

কেবল স্পষ্ট করে বলতে গেলে, আমার "ব্যবহার ... হিসাবে" ব্যবহারের উদাহরণটি সহজ করা হয়েছিল।

বিকল্পটি নিম্নলিখিত ছিল:

$class = new Person\Barnes\David\Class1();

অথবা

use Person\Barnes\David\Class1;

// ...

$class = new Class1();

1
আপনি ব্যবহার করতে হবে না AS। এই সমাধান কাজ করে না কেন। আপনি ঠিক তেমন সহজেই করতে পারেন: use Person\Barnes\David\Class1;(যা সমান use Person\Barnes\David\Class1 as Class1;)।
কার্টফোরহর্স

1
ধন্যবাদ, এটি কাজ করে। তবে আমি বুঝতে পারি না কেন আমরা কেবল $ শ্রেণি = নতুন ক্লাস 1 () ব্যবহার করতে পারি; যখন আমরা ইতিমধ্যে "ব্যক্তি \ বার্নস \ ডেভিড ব্যবহার করুন" সংজ্ঞায়িত করেছি?
ব্যবহারকারী345602

4
@ ব্যবহারকারী 346665 আপনাকে অবশ্যই এটি ব্যবহার use Person\Barnes\David\Class1;করতে হবে $class = new Class1();। সঙ্গে use Person\Barnes\David;আপনি কি করতে হবে $class = new David\Class1();useশব্দ নিজে এর সমতূল্য use Person\Barnes\David\Class1 as Class1;বা use Person\Barnes\David as David;প্রতিটি উদাহরণস্বরূপ, যথাক্রমে।
জাস্টিন সি

2018 এ যারা পড়ছেন তাদের জন্য @ spl_autoload_register- এর সাথে @ যুবরাজ-বিলি-গ্রাহাম সলিউশনটি ব্যবহার করুন
ব্রুনো ডি অলিভিয়র

26

পাস্কেল মার্টিন হিসাবে উল্লিখিত হিসাবে, আপনার উদাহরণস্বরূপ '\' DIRECTORY_SEPARATOR এর সাথে প্রতিস্থাপন করা উচিত:

$filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
include($filename);

কোডটি আরও পঠনযোগ্য করে তোলার জন্য আমি আপনাকে ডাইরেক্টরি কাঠামোর পুনর্গঠন করার পরামর্শ দেব। এটি বিকল্প হতে পারে:

ডিরেক্টরি কাঠামো:

ProjectRoot
 |- lib

ফাইল: /ProjectRoot/lib/Person/Barnes/David/Class1.php

<?php
namespace Person\Barnes\David
class Class1
{
    public function __construct()
    {
        echo __CLASS__;
    }
}
?>
  • আপনার সংজ্ঞায়িত প্রতিটি নেমস্পেসের জন্য উপ ডিরেক্টরি তৈরি করুন।

ফাইল: /ProjectRoot/test.php

define('BASE_PATH', realpath(dirname(__FILE__)));
function my_autoloader($class)
{
    $filename = BASE_PATH . '/lib/' . str_replace('\\', '/', $class) . '.php';
    include($filename);
}
spl_autoload_register('my_autoloader');

use Person\Barnes\David as MyPerson;
$class = new MyPerson\Class1();
  • আমি অটোলোডার ঘোষণার জন্য পিএইচপি 5 পুনঃব্যবহার ব্যবহার করেছি। আপনি যদি এখনও পিএইচপি 4 এর সাথে থাকেন তবে এটিকে পুরানো বাক্য গঠন দিয়ে প্রতিস্থাপন করুন: ফাংশন __autoload ($ শ্রেণি)

18

তোমার __autoload ফাংশনটি নেমস্পেসের নাম সহ পুরো ক্লাস-নামটি গ্রহণ করবে।

এর অর্থ, আপনার ক্ষেত্রে, __autoloadফাংশনটি ' Person\Barnes\David\Class1', এবং কেবল '' পাবেনClass1 ' পাবে না।

সুতরাং, আপনাকে এই ধরণের "আরও জটিল" নামটির সাথে মোকাবিলা করতে, আপনার অটলয়েডিং কোডটি সংশোধন করতে হবে; প্রায়শই ব্যবহৃত সমাধানটি হ'ল নামস্থানগুলির "স্তর" প্রতি ডিরেক্টরিটির একটি স্তর ব্যবহার করে আপনার ফাইলগুলি সংগঠিত করা এবং স্বয়ংক্রিয়ভাবে লোড করা হলে নামফলক নামটিতে ' \' প্রতিস্থাপন করুন DIRECTORY_SEPARATOR


1
এটি আমি খুঁজে পাইনি। আমি যখন বিবৃতিটি মরতে পারি ($ শ্রেণি); __autoload ফাংশনে, এটি 'ব্যক্তি 1 \ বার্নস \ ডেভিড \ Class1' নয়, 'ক্লাস 1' মুদ্রিত হয়েছে
ডেভিড বার্নস

সত্য। olo অটোল্যাডের ক্লাস প্যারামিটারটি বর্গ নাম যেমন কনস্ট্রাক্টর কলে লিখিত হয়।
তিশমা

1
ডাউনওয়েট "আপনার __autoloadফাংশনটি নেমস্পেসের নাম সহ পুরো ক্লাস-নামটি গ্রহণ করবে" - এটি কেবলমাত্র সত্য যদি আপনি useযে শ্রেণীর সাথে রেফারেন্স দেওয়ার চেষ্টা করছেন তা স্পষ্টভাবে ডি করিয়েছেন, যদি না আপনি কেবল যে নামটির সাথে সম্পর্কিত থাকেন তা নয় use। ওপি'র ভুলটি ছিল যে তিনি useএকটি শ্রেণি সম্বলিত নেমস্পেসটি চাইতেন এবং তারপরে তার অটোলোড ফাংশনটি যাদুবিদ্যার দ্বারা কোনওভাবে পুরো ক্লাসপথটি পাস করার আশা করছিল। এই উত্তরটি আসলে ওপি-র ভুলকেই সম্বোধন করে না।
মার্ক আমেরিকা


3

আমি এই রত্নটি ফ্লাইসিস্টেম থেকে পেয়েছি

spl_autoload_register(function($class) {
    $prefix = 'League\\Flysystem\\';

    if ( ! substr($class, 0, 17) === $prefix) {
        return;
    }

    $class = substr($class, strlen($prefix));
    $location = __DIR__ . 'path/to/flysystem/src/' . str_replace('\\', '/', $class) . '.php';

    if (is_file($location)) {
        require_once($location);
    }
});

3

আমি দেখতে পেয়েছি যে অটোলোড ফাংশনগুলি কেবলমাত্র "পূর্ণ" শ্রেণীর নামটি গ্রহণ করে - এতে সমস্ত নামস্থান আগে রয়েছে - নিম্নলিখিত দুটি ক্ষেত্রে:

[a] $a = new The\Full\Namespace\CoolClass();

[b] use The\Full\Namespace as SomeNamespace; (at the top of your source file) followed by $a = new SomeNamespace\CoolClass();

আমি দেখতে পাচ্ছি যে অটোলোড ফাংশনগুলি নিম্নলিখিত ক্ষেত্রে পুরো ক্লাসের নামটি গ্রহণ করে না:

[c] use The\Full\Namespace; (at the top of your source file) followed by $a = new CoolClass();

আপডেট: [সি] একটি ভুল এবং নেমস্পেসগুলি কীভাবে কাজ করে তা নয়। আমি জানাতে পারি যে, [সি] এর পরিবর্তে, নিম্নলিখিত দুটি ক্ষেত্রেও ভাল কাজ করা হয়েছে:

[d] use The\Full\Namespace; (at the top of your source file) followed by $a = new Namespace\CoolClass();

[e] use The\Full\Namespace\CoolClass; (at the top of your source file) followed by $a = new CoolClass();

আশাকরি এটা সাহায্য করবে.


পার্শ্ব নোট হিসাবে, useকীওয়ার্ড পিএইচপি ইন্টারেক্টিভ কমান্ড-লাইন ইন্টারফেসে ( php --interactive) সঠিকভাবে কাজ করে না ;
অ্যান্ড্রু লারসন

3

আমি এই সাধারণ হ্যাকটি এক লাইনে ব্যবহার করি:

spl_autoload_register(function($name){
        require_once 'lib/'.str_replace('\\','/',$name).'.php';
    });

1

একই সমস্যা ছিল এবং সবে এটি পাওয়া গেছে:

আপনি যখন অন্তর্ভুক্ত শ্রেণীর নামের জায়গাগুলির সাথে মিল রেখে একটি সাবফোল্ডার কাঠামো তৈরি করেন, আপনাকে কখনও অটোলোডারও নির্ধারণ করতে হবে না।

    spl_autoload_extensions(".php"); // comma-separated list
    spl_autoload_register();

এটি একটি মোহন মত কাজ করে

এখানে আরও তথ্য: http://www.php.net/manual/en/function.spl-autoload-register.php#92514

সম্পাদনা: ব্যাকস্ল্যাশের কারণে এটি লিনাক্সে সমস্যা সৃষ্টি করে ... immeëmosol দ্বারা সমাধানের জন্য এখানে দেখুন

নেমস্পেস অটোল্যাড উইন্ডোসের নীচে কাজ করে তবে লিনাক্সে নয়


1

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

spl_autoload_extensions(".php");
spl_autoload_register();

উদাহরণ স্বরূপ:

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

আপনার কোডে __autoload ব্যবহার করা এখনও পিএইচপি-র বর্তমান সংস্করণগুলির সাথে কাজ করতে পারে তবে ভবিষ্যতে এই বৈশিষ্ট্যটি অবচয় এবং অবশেষে অপসারণের প্রত্যাশা করে।

সুতরাং বিকল্পগুলি কি বাকি আছে:

এই সংস্করণটি পিএইচপি 5.3 এবং তারপরের উপরে কাজ করবে এবং সামসুপারক্লাস.ফ্প এবং সামসুপারক্লাস.পিপি ফাইলের জন্য অনুমতি দেয়। যদি আপনি 5.3.2 বা তার বেশি ব্যবহার করে থাকেন তবে এই অটোলোডার আরও দ্রুত কাজ করবে।

<?php

if ( function_exists ( 'stream_resolve_include_path' ) == false ) {
    function stream_resolve_include_path ( $filename ) {
        $paths = explode ( PATH_SEPARATOR, get_include_path () );
        foreach ( $paths as $path ) {
            $path = realpath ( $path . PATH_SEPARATOR . $filename );
            if ( $path ) {
                return $path;
            }
        }
        return false;
    }
}

spl_autoload_register ( function ( $className, $fileExtensions = null ) {
    $className = str_replace ( '_', '/', $className );
    $className = str_replace ( '\\', '/', $className );
    $file = stream_resolve_include_path ( $className . '.php' );
    if ( $file === false ) {
        $file = stream_resolve_include_path ( strtolower ( $className . '.php' ) );
    }
    if ( $file !== false ) {
        include $file;
        return true;
    }
    return false;
});

2
পার্শ্ব নোট হিসাবে, str_replace ([ '_','\\'] '/', $className );দুটি ত্রৈমাসিকের চেয়ে দ্বিগুণ দ্রুত
Itay Moav -Malimovka

যতক্ষণ না পিএইচপি ফাইলটি উপরের / লোয়ার কেসড হয় তা কার্যকর নয়, ডিরেক্টরিগুলি এখনও সংবেদনশীল থেকে যায়
মাইক

1

আমি সম্প্রতি ট্যানারকুকের উত্তরটি খুব সহায়ক বলে খুঁজে পেয়েছি! কেবল যোগ করতে চেয়েছিলেন যে strrpos()+ ব্যবহারের substr()চেয়ে explode()+ end(): এর চেয়ে কিছুটা দ্রুত

spl_autoload_register( function( $class ) {
    $pos = strrpos( $class, '\\' );
    include ( $pos === false ? $class : substr( $class, $pos + 1 ) ).'.php';
});

1

আমি আপেক্ষিক প্রারম্ভিক বা সমস্ত তত্ত্ব ছাড়াই একটি সহজ spl_autoload_register () সেটআপ চাই না জন্য আমার দুটি সেন্ট নিক্ষেপ করব: প্রতিটি ক্লাসের জন্য কেবল একটি পিএইচপি ফাইল তৈরি করুন, সেই পিএইচপি ফাইলটিকে আপনার শ্রেণীর নামের মতো করুন, এবং আপনার ক্লাসের ফাইলগুলি রাখুন প্রশ্নে আপনার পিএইচপি ফাইল হিসাবে একই ডিরেক্টরিতে, তারপর এটি কাজ করবে:

spl_autoload_register(function ($class_name) {
    require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . $class_name . '.php';
});

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


1

https://thomashunter.name/blog/simple-php-namespace-friendly-autoloader-class/

আপনি আপনার ক্লাসের ফাইলগুলি নামের ফোল্ডারে রাখতে চান Classesযা আপনার পিএইচপি অ্যাপ্লিকেশনটিতে প্রবেশের পয়েন্ট হিসাবে একই ডিরেক্টরিতে রয়েছে। ক্লাসগুলি যদি নেমস্পেস ব্যবহার করে তবে নামস্থানগুলি ডিরেক্টরি কাঠামোতে রূপান্তরিত হবে।

প্রচুর অন্যান্য অটো-লোডারগুলির বিপরীতে, আন্ডারস্কোরগুলি ডিরেক্টরি স্ট্রাকচারে রূপান্তরিত হবে না (পিএইচপি <5.3 সিউডো নেমস্পেসের সাথে পিএইচপি> = 5.3 আসল নেমস্পেসগুলি করা জটিল)।

<?php
class Autoloader {
    static public function loader($className) {
        $filename = "Classes/" . str_replace("\\", '/', $className) . ".php";
        if (file_exists($filename)) {
            include($filename);
            if (class_exists($className)) {
                return TRUE;
            }
        }
        return FALSE;
    }
}
spl_autoload_register('Autoloader::loader');

আপনি নিম্নলিখিত কোডটি আপনার প্রধান পিএইচপি স্ক্রিপ্টে প্রবেশ করতে চাইবেন (এন্ট্রি পয়েন্ট):

require_once("Classes/Autoloader.php");

এখানে ডিরেক্টরি উদাহরণ একটি উদাহরণ:

index.php
Classes/
  Autoloader.php
  ClassA.php - class ClassA {}
  ClassB.php - class ClassB {}
  Business/
    ClassC.php - namespace Business; classC {}
    Deeper/
      ClassD.php - namespace Business\Deeper; classD {}

0
<?php
spl_autoload_register(function ($classname){
   // for security purpose
   //your class name should match the name of your class "file.php"
   $classname = str_replace("..", "", $classname);
   require_once __DIR__.DIRECTORY_SEPARATOR.("classes/$classname.class.php");
});
try {
  $new = new Class1();
} catch (Exception $e) {
   echo "error = ". $e->getMessage();
}
?>

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