পিএইচপি 5 এ সিঙ্গলটন ডিজাইন প্যাটার্ন তৈরি করা


204

কীভাবে একজন পিএইচপি 5 ক্লাস ব্যবহার করে একটি সিঙ্গলটন ক্লাস তৈরি করবেন?



1
@ অ্যান্ড্রু ড্যান্ট ডাটাবেসের সাথে সংযোগ স্থাপনের পরে দ্বিতীয় বার ইনস্ট্যান্ট করবেন না। যেখানে প্রয়োজন সেখানে সেই দৃষ্টান্তটি দিন। সিঙ্গেলনের প্রয়োজনীয়তা হ'ল একটি কোড গন্ধ। Gooh.posterous.com/singletons-in-php-
গর্ডন

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

3
@ অ্যান্ড্রু: আপনি এখন ধরে নিয়েছেন যে আপনার কেবল একটি ডাটাবেস সংযোগ প্রয়োজন। আপনার প্রয়োজনীয়তাগুলি পরিবর্তিত হয় এবং আপনাকে 2 ডাটাবেস সার্ভারের সাথে কথা বলতে গেলে কী হয়? আপনি যদি আপনার দলটিকে সঠিকভাবে কাজ করতে বিশ্বাস করতে না পারেন তবে তা উল্লেখ করার দরকার নেই , একটি সিঙ্গলটন তৈরি করা আপনাকে কিছুটা হলেও সহায়তা করবে না। শুরু থেকেই জিনিসগুলি করুন এবং এমন একটি দল পান যা আপনি বিশ্বাস করতে পারেন এবং আপনি ভাল থাকবেন।
ইরকম্যাক্সেল

4
কেবলমাত্র সিঙ্গলটন অতিরিক্ত ব্যবহার করা হয়েছে এটিকে এড়াতে হবে এমন একটি খারাপ প্যাটার্ন তৈরি করে না। সিঙ্গলটনে ঘৃণা করবেন না। কখনও কখনও এটি একটি নির্দিষ্ট সমস্যার পুরোপুরি ভাল সমাধান। আবেগগতভাবে একে হ্রাস করার চেষ্টা করার পরিবর্তে কেন আমাদের এটি ব্যবহার করা উচিত নয় তা নিয়ে তর্ক শুরু করা ভাল।
গিলস লেসিরে

উত্তর:


268
/**
 * Singleton class
 *
 */
final class UserFactory
{
    /**
     * Call this method to get singleton
     *
     * @return UserFactory
     */
    public static function Instance()
    {
        static $inst = null;
        if ($inst === null) {
            $inst = new UserFactory();
        }
        return $inst;
    }

    /**
     * Private ctor so nobody else can instantiate it
     *
     */
    private function __construct()
    {

    }
}

ব্যবহার করা:

$fact = UserFactory::Instance();
$fact2 = UserFactory::Instance();

$fact == $fact2;

কিন্তু:

$fact = new UserFactory()

একটি ত্রুটি নিক্ষেপ।

স্থির পরিবর্তনশীল স্কোপগুলি এবং সেটিং কেন কাজ করে তা বুঝতে http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static দেখুন ststatic $inst = null;


59
দুটি দৃষ্টান্ত তুলনা করতে আপনার == পরিবর্তে === ব্যবহার করা উচিত। == সত্য ফিরে আসবে যদি $ ফ্যাক্ট 1 এবং $ ফ্যাক্ট 2 উভয় একই শ্রেণীর হয় তবে === কেবলমাত্র সত্যটি প্রত্যাবর্তন হয় যদি তারা উভয়ই একই বস্তুর একই উদাহরণ instance
কিথ টমম্বলি

10
ক্লোন পদ্ধতিটিও ব্যক্তিগত হওয়া উচিত
অ্যালেক্স পেট্রোভ

22
আপনি যখন ইনস্ট্যান্স () এ কল করবেন তখন এই পদ্ধতিটি ইউজারফ্যাক্টরির উদাহরণটি পুনরায় সেট করবে না? জাভাতে $ ইনস্টিটিটিভ ভেরিয়েবলটি একটি প্রাইভেট স্ট্যাটিক বৈশিষ্ট্য হবে যা বারবার পুনরায় সেট করা উচিত নয়, অন্যথায় আপনি সম্ভবত এটি একটি সিঙ্গলটন নাও তৈরি করতে পারেন।
রুডি গার্সিয়া

8
ফাংশনে স্থির হিসাবে চলকটি কীভাবে এবং কীভাবে ঘোষণার বিষয়টি লেখকের উদ্দেশ্য হিসাবে কাজ করে তার একটি ভাল লেখার জন্য এখানে রয়েছে: php.net/manual/en/…
hereswhatidid

10
আপনার should inst = নতুন স্ব () ব্যবহার করা উচিত; not $ inst = নতুন ইউজারফ্যাক্টরি (); যে কেউ পরে এই জুড়ে আসা। পিএইচপি পদ্ধতিতে অন্তর্নির্মিত ব্যবহারের জন্য +1।
লিগমার

119

পিএইচপি 5.3 লেট স্ট্যাটিক বাইন্ডিংয়ের মাধ্যমে উত্তরাধিকারসূত্রে সিঙ্গলটন ক্লাস তৈরির অনুমতি দেয়:

class Singleton
{
    protected static $instance = null;

    protected function __construct()
    {
        //Thou shalt not construct that which is unconstructable!
    }

    protected function __clone()
    {
        //Me not like clones! Me smash clones!
    }

    public static function getInstance()
    {
        if (!isset(static::$instance)) {
            static::$instance = new static;
        }
        return static::$instance;
    }
}

এটি সমস্যার সমাধান করে, পিএইচপি 5.3 এর পূর্বে যে কোনও শ্রেণি যে একটি সিঙ্গলটন বাড়িয়েছিল তার নিজস্ব পরিবর্তে তার পিতামাত্ত শ্রেণীর উদাহরণ তৈরি করবে।

এখন আপনি এটি করতে পারেন:

class Foobar extends Singleton {};
$foo = Foobar::getInstance();

এবং oo foo সিঙ্গেলনের উদাহরণের পরিবর্তে ফুবারের উদাহরণ হবে।


1
দেরী স্ট্যাটিক বাঁধাই পিএইচপি 5.3 এ আসলেই খুব ভাল জিনিস। খুব খারাপ আমি এখনও এটি ব্যবহার করতে পারি না।
আন্তোনিওসিএস

4
@Ggsonic থেকে: "subclass should own its own static var. check this: echo get_class(Foobar::getInstance());echo get_class(Singleton::getInstance());"
ব্রুক অ্যাডামস

4
এটি মোটেই কাজ করে না, কেবল তাই ঘটে যে ফুবার আপনার নির্মিত প্রথম শ্রেণীর ছিল?
ক্রিস কেএল

1
ক্লোন করার এখনও একটি সম্ভাবনা ..... "$ a = সিঙ্গলটন :: getInstance (); $ বি = আনসিরিয়ালাইজ (সিরিয়ালাইজ ($ এ)); $ এ! == $ বি;"
বোর্চুনাক

15
যখন একাধিক সাবক্লাস থাকে তখন এটি কাজ করে না! $instanceসাবক্লাস নয়, সিঙ্গেলনে থাকে। কিছু সাবক্লাস তাত্ক্ষণিকভাবে চালু হওয়ার পরে, getInstance () সমস্ত উপক্লাসের জন্য সেই উদাহরণটি ফিরিয়ে দেবে।
এমপার্টেল

116

দুর্ভাগ্যক্রমে Inwdr এর উত্তরটি যখন একাধিক সাবক্ল্যাস থাকে s

এখানে একটি সঠিক উত্তরাধিকারসূত্রে সিঙ্গলটন বেস শ্রেণি রয়েছে।

class Singleton
{
    private static $instances = array();
    protected function __construct() {}
    protected function __clone() {}
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    public static function getInstance()
    {
        $cls = get_called_class(); // late-static-bound class name
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static;
        }
        return self::$instances[$cls];
    }
}

পরীক্ষার কোড:

class Foo extends Singleton {}
class Bar extends Singleton {}

echo get_class(Foo::getInstance()) . "\n";
echo get_class(Bar::getInstance()) . "\n";

1
এটি একক বাস্তবায়ন সংশোধনের এতদূর নিকটতম। অপ্রয়োজনীয়করণ রোধ করার জন্য আপনার __Wakeup () পদ্ধতিতে নিক্ষেপ করাও বিবেচনা করা উচিত ।
রবার্ট রোসম্যান

আসলে আপনাকে হয় একটি ব্যতিক্রম ছুঁড়ে ফেলতে হবে বা ম্যানুয়ালি একটি ত্রুটি উত্থাপন করতে হবে - ফাংশনটিকে সুরক্ষিত / ব্যক্তিগত হিসাবে ঘোষণা করা কেবল একটি E_WARNING উত্থাপন করবে যে এটি পদ্ধতিটিতে অ্যাক্সেস করতে পারে না, তবে অন্যথায় চালিয়ে যাবে।
রবার্ট রসম্যান 21

ধন্যবাদ। আমি সাধারণত সমস্ত সতর্কতা ইত্যাদি ব্যাতিক্রমে রূপান্তরিত করেছি, তাই আমি পরীক্ষার সময় পার্থক্যটি ভুলে গিয়েছিলাম: পি
এমপারটেল

এটিই কেবলমাত্র একমাত্র সমাধান যা আমি খুঁজে পেয়েছি যে একাধিক সাব-শ্রেণীর সাথে সঠিকভাবে কাজ করে। ধন্যবাদ!
বব ড্যানকার্ট

36

একক প্যাটার্ন তৈরির আসল এক এবং আধুনিক উপায় হ'ল:

<?php

/**
 * Singleton Pattern.
 * 
 * Modern implementation.
 */
class Singleton
{
    /**
     * Call this method to get singleton
     */
    public static function instance()
    {
      static $instance = false;
      if( $instance === false )
      {
        // Late static binding (PHP 5.3+)
        $instance = new static();
      }

      return $instance;
    }

    /**
     * Make constructor private, so nobody can call "new Class".
     */
    private function __construct() {}

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

সুতরাং এখন আপনি এটি পছন্দ মত ব্যবহার করতে পারেন।

<?php

/**
 * Database.
 *
 * Inherited from Singleton, so it's now got singleton behavior.
 */
class Database extends Singleton {

  protected $label;

  /**
   * Example of that singleton is working correctly.
   */
  public function setLabel($label)
  {
    $this->label = $label;
  }

  public function getLabel()
  {
    return $this->label;
  }

}

// create first instance
$database = Database::instance();
$database->setLabel('Abraham');
echo $database->getLabel() . PHP_EOL;

// now try to create other instance as well
$other_db = Database::instance();
echo $other_db->getLabel() . PHP_EOL; // Abraham

$other_db->setLabel('Priler');
echo $database->getLabel() . PHP_EOL; // Priler
echo $other_db->getLabel() . PHP_EOL; // Priler

আপনি যেমন দেখেন যে এই উপলব্ধিটি আরও নমনীয়।


4
এই থ্রেডের মধ্যে একক প্যাটার্ন সম্পর্কে এটি পরিষ্কার the ধন্যবাদ।
গস

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

মধ্যে instanceফাংশন $instanceহওয়া উচিত nullনাfalse
Mifas

হ্যাঁ, তবে এটি কার্যকরী নয়, তবে পদ্ধতি।
আব্রাহাম তুগালভ

26

কোনও ঘটনার ক্লোনিং বর্জন করার জন্য আপনার সম্ভবত একটি ব্যক্তিগত __ ক্লোন () পদ্ধতি যুক্ত করা উচিত।

private function __clone() {}

আপনি যদি এই পদ্ধতিটি অন্তর্ভুক্ত না করেন তবে নিম্নলিখিতগুলি সম্ভব হয়ে ওঠে

$inst1=UserFactory::Instance(); // to stick with the example provided above
$inst2=clone $inst1;

এখন $inst1! == $inst2- তারা আর একই উদাহরণ নয়।


11
<?php
/**
 * Singleton patter in php
 **/
trait SingletonTrait {
   protected static $inst = null;

  /**
   * call this method to get instance
   **/
   public static function getInstance(){
      if (static::$inst === null){
         static::$inst = new static();
      }
      return static::$inst;
  }

  /**
   * protected to prevent clonning 
   **/
  protected function __clone(){
  }

  /**
   * protected so no one else can instance it 
   **/
  protected function __construct(){
  }
}

ব্যবহার করা:

/**
 *  example of class definitions using SingletonTrait
 */
class DBFactory {
  /**
   * we are adding the trait here 
   **/
   use SingletonTrait;

  /**
   * This class will have a single db connection as an example
   **/
  protected $db;


 /**
  * as an example we will create a PDO connection
  **/
  protected function __construct(){
    $this->db = 
        new PDO('mysql:dbname=foodb;port=3305;host=127.0.0.1','foouser','foopass');
  }
}
class DBFactoryChild extends DBFactory {
  /**
   * we repeating the inst so that it will differentiate it
   * from UserFactory singleton
   **/
   protected static $inst = null;
}


/**
 * example of instanciating the classes
 */
$uf0 = DBFactoryChild::getInstance();
var_dump($uf0);
$uf1 = DBFactory::getInstance();
var_dump($uf1);
echo $uf0 === $uf1;

respose:

object(DBFactoryChild)#1 (0) {
}
object(DBFactory)#2 (0) {
}

আপনি যদি পিএইচপি 5.4 ব্যবহার করছেন: এটির একটি বিকল্প বৈশিষ্ট্য , যাতে সিঙ্গেলনের প্যাটার্নটি পেতে আপনাকে উত্তরাধিকারের স্তরক্রম নষ্ট করতে হবে না

এবং আরও খেয়াল করুন যে আপনি সিঙ্গলটন ক্লাসের প্রথম বৈশিষ্টগুলি ব্যবহার করেন বা প্রসারিত করেন তা হ'ল যদি আপনি নিম্নোক্ত কোডের লাইনটি যুক্ত না করেন তবে শিশু ক্লাসগুলির সিঙ্গলটন তৈরি করা ছিল:

   protected static $inst = null;

শিশু শ্রেণিতে

অপ্রত্যাশিত ফলাফল হবে:

object(DBFactoryChild)#1 (0) {
}
object(DBFactoryChild)#1 (0) {
}

10
protected  static $_instance;

public static function getInstance()
{
    if(is_null(self::$_instance))
    {
        self::$_instance = new self();
    }
    return self::$_instance;
}

এই কোডটি তার শ্রেণীর নাম সম্পর্কে চিন্তা না করে যে কোনও শ্রেণির জন্য আবেদন করতে পারে।


8

প্রতি ক্লাসে 1 টি লাইন সহ একাধিক অবজেক্ট সমর্থন করে:

এই পদ্ধতিটি আপনার ইচ্ছা অনুযায়ী যে কোনও শ্রেণিতে সিঙ্গেলন প্রয়োগ করবে, আপনাকে যা করতে হবে সেই ক্লাসে 1 পদ্ধতি যুক্ত করতে হবে যা আপনি সিঙ্গলটন বানাতে চান এবং এটি আপনার জন্য এটি করবে।

এটি "সিঙ্গেলটনবেস" শ্রেণিতে অবজেক্টগুলিও সঞ্চয় করে যাতে আপনি আপনার সিস্টেমে আপনার সমস্ত বস্তুগুলি ডিবাগ করতে পারেন যা আপনি SingleTonBaseবস্তুর পুনরাবৃত্তি করে ব্যবহার করতে পারেন ।


সিঙ্গলটনবেস.এফপি নামে একটি ফাইল তৈরি করুন এবং এটি আপনার স্ক্রিপ্টের মূলের মধ্যে অন্তর্ভুক্ত করুন!

কোডটি হ'ল

abstract class SingletonBase
{
    private static $storage = array();

    public static function Singleton($class)
    {
        if(in_array($class,self::$storage))
        {
            return self::$storage[$class];
        }
        return self::$storage[$class] = new $class();
    }
    public static function storage()
    {
       return self::$storage;
    }
}

তারপরে যে কোনও শ্রেণীর জন্য আপনি একটি সিঙ্গলটন বানাতে চান কেবল এই ছোট একক পদ্ধতি যুক্ত করুন।

public static function Singleton()
{
    return SingletonBase::Singleton(get_class());
}

এখানে একটি ছোট উদাহরণ:

include 'libraries/SingletonBase.resource.php';

class Database
{
    //Add that singleton function.
    public static function Singleton()
    {
        return SingletonBase::Singleton(get_class());
    }

    public function run()
    {
        echo 'running...';
    }
}

$Database = Database::Singleton();

$Database->run();

এবং আপনি যে কোনও ক্লাসে এই সিঙ্গলটন ফাংশনটি যুক্ত করতে পারেন এবং এটি প্রতি ক্লাসে 1 টি উদাহরণ তৈরি করবে।

দ্রষ্টব্য: নতুন ক্লাসের ব্যবহার () ব্যবহারের অপসারণের জন্য আপনার সর্বদা __কাউন্টচারকে ব্যক্তিগত করা উচিত; instantiations।


5
class Database{

        //variable to hold db connection
        private $db;
        //note we used static variable,beacuse an instance cannot be used to refer this
        public static $instance;

        //note constructor is private so that classcannot be instantiated
        private function __construct(){
          //code connect to database  

         }     

         //to prevent loop hole in PHP so that the class cannot be cloned
        private function __clone() {}

        //used static function so that, this can be called from other classes
        public static function getInstance(){

            if( !(self::$instance instanceof self) ){
                self::$instance = new self();           
            }
             return self::$instance;
        }


        public function query($sql){
            //code to run the query
        }

    }


Access the method getInstance using
$db = Singleton::getInstance();
$db->query();

5

আপনার সত্যই সিঙ্গলটন প্যাটার্ন ব্যবহার করার দরকার নেই কারণ এটি এন্টিপ্যাটার্ন হিসাবে বিবেচিত হয়। মূলত এই প্যাটার্নটি একেবারেই বাস্তবায়ন না করার অনেক কারণ রয়েছে। শুরু করার জন্য এটি পড়ুন: পিএইচপি সিঙ্গলটন ক্লাসে সেরা অনুশীলন

যদি আপনি এখনও মনে করেন যে আপনার সিঙ্গলটন প্যাটার্নটি ব্যবহার করা প্রয়োজন তবে আমরা একটি ক্লাস লিখতে পারি যা আমাদের সিঙ্গলটন ক্লাসভেন্ডার বিমূর্ত শ্রেণীর প্রসারিত করে সিঙ্গেলন কার্যকারিতা পেতে দেয়।

আমি এই সমস্যাটি সমাধান করতে এসেছি।

<?php
namespace wl;


/**
 * @author DevWL
 * @dosc allows only one instance for each extending class.
 * it acts a litle bit as registry from the SingletonClassVendor abstract class point of view
 * but it provides a valid singleton behaviour for its children classes
 * Be aware, the singleton pattern is consider to be an anti-pattern
 * mostly because it can be hard to debug and it comes with some limitations.
 * In most cases you do not need to use singleton pattern
 * so take a longer moment to think about it before you use it.
 */
abstract class SingletonClassVendor
{
    /**
     *  holds an single instance of the child class
     *
     *  @var array of objects
     */
    protected static $instance = [];

    /**
     *  @desc provides a single slot to hold an instance interchanble between all child classes.
     *  @return object
     */
    public static final function getInstance(){
        $class = get_called_class(); // or get_class(new static());
        if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
            self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
            echo "new ". $class . PHP_EOL; // remove this line after testing
            return  self::$instance[$class]; // remove this line after testing
        }
        echo "old ". $class . PHP_EOL; // remove this line after testing
        return static::$instance[$class];
    }

    /**
     * Make constructor abstract to force protected implementation of the __constructor() method, so that nobody can call directly "new Class()".
     */
    abstract protected function __construct();

    /**
     * Make clone magic method private, so nobody can clone instance.
     */
    private function __clone() {}

    /**
     * Make sleep magic method private, so nobody can serialize instance.
     */
    private function __sleep() {}

    /**
     * Make wakeup magic method private, so nobody can unserialize instance.
     */
    private function __wakeup() {}

}

উদাহরণ ব্যবহার করুন:

/**
 * EXAMPLE
 */

/**
 *  @example 1 - Database class by extending SingletonClassVendor abstract class becomes fully functional singleton
 *  __constructor must be set to protected becaouse: 
 *   1 to allow instansiation from parent class 
 *   2 to prevent direct instanciation of object with "new" keword.
 *   3 to meet requierments of SingletonClassVendor abstract class
 */
class Database extends SingletonClassVendor
{
    public $type = "SomeClass";
    protected function __construct(){
        echo "DDDDDDDDD". PHP_EOL; // remove this line after testing
    }
}


/**
 *  @example 2 - Config ...
 */
class Config extends SingletonClassVendor
{
    public $name = "Config";
    protected function __construct(){
        echo "CCCCCCCCCC" . PHP_EOL; // remove this line after testing
    }
}

এটি প্রত্যাশার মতো কাজ করে তা প্রমাণ করার জন্য:

/**
 *  TESTING
 */
$bd1 = Database::getInstance(); // new
$bd2 = Database::getInstance(); // old
$bd3 = Config::getInstance(); // new
$bd4 = Config::getInstance(); // old
$bd5 = Config::getInstance(); // old
$bd6 = Database::getInstance(); // old
$bd7 = Database::getInstance(); // old
$bd8 = Config::getInstance(); // old

echo PHP_EOL."COMPARE ALL DATABASE INSTANCES".PHP_EOL;
var_dump($bd1);
echo '$bd1 === $bd2' . ($bd1 === $bd2)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd2 === $bd6' . ($bd2 === $bd6)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd6 === $bd7' . ($bd6 === $bd7)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE

echo PHP_EOL;

echo PHP_EOL."COMPARE ALL CONFIG INSTANCES". PHP_EOL;
var_dump($bd3);
echo '$bd3 === $bd4' . ($bd3 === $bd4)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd4 === $bd5' . ($bd4 === $bd5)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd5 === $bd8' . ($bd5 === $bd8)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE

আরও উচ্চতর উত্তর পড়ার সময় আমার মনে এই জাতীয় কিছু ছিল। ভাগ্যক্রমে এটি ইতিমধ্যে এখানে ছিল :)
نفرت 13

3

এই সমস্ত জটিলতা ("লেট স্ট্যাটিক বাইন্ডিং" ... হারাম্ফ) আমার কাছে কেবল পিএইচপি'র ভাঙা অবজেক্ট / শ্রেণির মডেলের একটি চিহ্ন। যদি শ্রেণি অবজেক্টগুলি প্রথম শ্রেণীর অবজেক্ট (পাইথন দেখুন) হয়, তবে "in _ইনস্ট্যান্স" একটি শ্রেণীর উদাহরণ হতে পারে পরিবর্তনশীল - শ্রেণীর অবজেক্টের সদস্য, তার উদাহরণগুলির সদস্য / সম্পত্তির বিপরীতে এবং ভাগ করার বিরোধিতা হিসাবে এর বংশধরদের দ্বারা স্মার্টটাক বিশ্বে এটি একটি "শ্রেণীর ভেরিয়েবল" এবং একটি "শ্রেণীর উদাহরণ ভেরিয়েবল" এর মধ্যে পার্থক্য।

পিএইচপি-তে, আমার কাছে এটি এমন মনে হয়েছে যেন আমাদের সেই নির্দেশনাটি হৃদয়গ্রাহ্য করা দরকার যে নিদর্শনগুলি লেখার কোডের দিক নির্দেশক - আমরা সম্ভবত একটি সিঙ্গলটন টেম্পলেট সম্পর্কে ভাবতে পারি, তবে কোডটি লেখার চেষ্টা করছি যা প্রকৃত "একক" ক্লাসের উত্তরাধিকার সূত্রে প্রাপ্ত পিএইচপি-র জন্য বিপথগামী দেখায় (যদিও আমার ধারণা ছিল যে কিছু উদ্যোগী ব্যক্তি একটি উপযুক্ত এসভিএন কীওয়ার্ড তৈরি করতে পারে)।

আমি একটি ভাগ করা টেম্পলেট ব্যবহার করে প্রতিটি সিঙ্গলটনকে পৃথকভাবে কোড করতে থাকব।

লক্ষ্য করুন যে আমি একেবারে একাকী-অশুভ আলোচনার বাইরে রয়েছি, জীবন খুব ছোট।


পিএইচপি ভাষার ক্রমবর্ধমান জটিলতা দেখার সময় আপনার মন্তব্যগুলি ঠিক। দেখে মনে হচ্ছে অনেকগুলি নতুন কোডিং প্যারাডিমগুলিতে অনেকগুলি বিভিন্ন ডিজাইনের ছিদ্র থেকে বেরিয়ে আসার জন্য অনেক নতুন কীওয়ার্ড যুক্ত করা হচ্ছে। সবচেয়ে খারাপ, পরিবর্তনের উচ্চ হারের কারণে এবং হোস্ট এবং ডেভেলপমেন্ট প্ল্যাটফর্মগুলি জুড়ে সংস্করণ স্কিউ হওয়ার কারণে, আজকের "সমাধান ডু ভ্রমণ" (@ এরিক অ্যান্ডারসনের উত্তরের বৈশিষ্ট্যগুলির মতো [স্ট্যাকওভারফ্লো.com/a/23998306/3696363 ] ) কাজ করবে না প্রোডাকশন সিস্টেমে যেগুলি সম্ভবত "সর্বশেষতম, সেরা" এর পরিবর্তে একটি "স্থিতিশীল" সংস্করণ চলছে running
এলিয়াহু স্কোকজিলাস

2

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

এখানে একটি উদাহরণ রয়েছে: আমি আমার নিজের এমভিসি এবং টেম্প্লেটিং ইঞ্জিনটি রোল করার সিদ্ধান্ত নিয়েছিলাম কারণ আমি সত্যিই কিছুটা হালকা ওজনের চেয়েছিলাম। যাইহোক, আমি যে ডেটাটি প্রদর্শন করতে চাইছি তাতে প্রচুর বিশেষ গণিতের অক্ষর রয়েছে যেমন ≥ এবং μ এবং আপনার কী রয়েছে ... ডেটাটি পূর্ব-এইচটিএমএল-এনকোডের পরিবর্তে আমার ডাটাবেসে প্রকৃত ইউটিএফ -8 অক্ষর হিসাবে সংরক্ষণ করা হয় কারণ আমার অ্যাপ্লিকেশনটি HTML ছাড়াও অন্যান্য ফর্ম্যাটগুলি যেমন পিডিএফ এবং সিএসভি বিতরণ করতে পারে deliver এইচটিএমএলের জন্য ফর্ম্যাট করার উপযুক্ত স্থানটি টেমপ্লেটের অভ্যন্তরে রয়েছে (যদি আপনি "দেখুন") যা পৃষ্ঠার অংশটি (স্নিপেট) রেন্ডারিংয়ের জন্য দায়ী। আমি তাদের যথাযথ এইচটিএমএল সত্তায় রূপান্তর করতে চাই, তবে পিএইচপিগুলি get_html_translation_table () ফাংশনটি অতি দ্রুত নয়। এটি একবারে ডেটা পুনরুদ্ধার করা এবং অ্যারে হিসাবে সঞ্চয় করার জন্য এটি আরও ভাল ধারণা দেয়, এটি সবার ব্যবহারের জন্য উপলব্ধ করে তোলে। এখানে' সা নমুনা আমি গতি পরীক্ষা করতে একসাথে নক করলাম সম্ভবত, আপনি যে অন্যান্য পদ্ধতি ব্যবহার করেন (উদাহরণটি পাওয়ার পরে) তা স্থির ছিল কিনা তা নির্বিশেষে এটি কাজ করবে।

class EncodeHTMLEntities {

    private static $instance = null;//stores the instance of self
    private $r = null;//array of chars elligalbe for replacement

    private function __clone(){
    }//disable cloning, no reason to clone

    private function __construct()
    {
        $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
        $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
        $this->r = array_diff($allEntities, $specialEntities);
    }

    public static function replace($string)
    {
        if(!(self::$instance instanceof self) ){
            self::$instance = new self();
        }
        return strtr($string, self::$instance->r);
    }
}
//test one million encodings of a string
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $dump = EncodeHTMLEntities::replace("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)");
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds using singleton\n";
//now repeat the same without using singleton
$start = microtime(true);
for($x=0; $x<1000000; $x++){
    $allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
    $specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
    $r = array_diff($allEntities, $specialEntities);
    $dump = strtr("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)", $r);
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds without using singleton";

মূলত, আমি এর মতো সাধারণ ফলাফল দেখেছি:

পিএইচপি টেস্ট.এফপি
রান সময়: সিঙ্গেলটন ব্যবহার করে 27.842966794968 সেকেন্ড
রান সময়: 237.78191494942 সেকেন্ড সিঙ্গলটন ব্যবহার না করে

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

এছাড়াও, আমি উদাহরণগুলি পছন্দ করি যা প্রকৃতপক্ষে কিছু করে, যেহেতু কখনও কখনও উদাহরণটিতে "// এখানে কিছু উপকারী করার মতো" বিবৃতি অন্তর্ভুক্ত থাকে যা টিউটোরিয়ালগুলির সন্ধানের সময় আমি সব সময় দেখি visual

যাইহোক, আমি এই জাতীয় জিনিসের জন্য সিঙ্গেলটন ব্যবহার ক্ষতিকারক (বা অত্যধিক জটিল) সম্পর্কে কোনও মতামত বা মন্তব্য পছন্দ করব।


1

এই নিবন্ধটি বেশ বিস্তৃতভাবে বিষয়কে কভার করে: http://www.phptherightway.com/pages/Design-Patterns.html#singleton

নিম্নলিখিত নোট:

  • অপারেটরের মাধ্যমে শ্রেণীর বাইরে কোনও নতুন উদাহরণ তৈরি করা রোধ করতে কনস্ট্রাক্টরকে __construct()ঘোষণা করা protectedহয় new
  • অপারেটরের মাধ্যমে ক্লাসের কোনও উদাহরণ ক্লোন করা রোধ করার জন্য যাদু পদ্ধতিটি __clone()ঘোষিত হয় ।privateclone
  • জাদু পদ্ধতিটি বিশ্বব্যাপী ফাংশনের মাধ্যমে শ্রেণীর কোনও উদাহরণের unserialization প্রতিরোধ __wakeup()হিসাবে ঘোষণা করা privateহয় unserialize()
  • একটি নতুন দৃষ্টান্ত প্রয়াত স্ট্যাটিক স্ট্যাটিক সৃষ্টি পদ্ধতিতে বাঁধাই মাধ্যমে তৈরি করা হয় getInstance()শব্দ সঙ্গে static। এটি class Singletonউদাহরণের সাবক্লাসিংয়ের অনুমতি দেয় ।

1

আমি এখানে ভাগ করে নেওয়ার চিন্তা ভাবনা লিখেছি

class SingletonDesignPattern {

    //just for demo there will be only one instance
    private static $instanceCount =0;

    //create the private instance variable
    private static $myInstance=null;

    //make constructor private so no one create object using new Keyword
    private function  __construct(){}

    //no one clone the object
    private function  __clone(){}

    //avoid serialazation
    public function __wakeup(){}

    //ony one way to create  object
    public static  function  getInstance(){

        if(self::$myInstance==null){
            self::$myInstance=new SingletonDesignPattern();
            self::$instanceCount++;
        }
        return self::$myInstance;
    }

    public static function getInstanceCount(){
        return self::$instanceCount;
    }

}

//now lets play with singleton design pattern

$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();

echo "number of instances: ".SingletonDesignPattern::getInstanceCount();

0

আমি প্রথম উত্তরের সাথে একমত তবে আমি ক্লাসটিও চূড়ান্ত হিসাবে ঘোষণা করব যাতে এটি বাড়ানো যায় না কারণ একটি সিঙ্গলটন বাড়ানো সিঙ্গলটন প্যাটার্ন লঙ্ঘন করে। এছাড়াও উদাহরণের পরিবর্তনশীলটি ব্যক্তিগত হওয়া উচিত যাতে এটি সরাসরি অ্যাক্সেস করা যায় না। এছাড়াও __ক্লোন পদ্ধতিটি ব্যক্তিগত করুন যাতে আপনি সিঙ্গলটন অবজেক্টটি ক্লোন করতে না পারেন।

নীচে কিছু উদাহরণ কোড দেওয়া আছে।

/**
 * Singleton class
 *
 */
final class UserFactory
{
    private static $_instance = null;

    /**
     * Private constructor
     *
     */
    private function __construct() {}

    /**
     * Private clone method
     *
     */
     private function __clone() {}

    /**
     * Call this method to get singleton
     *
     * @return UserFactory
     */
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new UserFactory();
        }
        return self::$_instance;
    }
}

ব্যবহারের উদাহরণ

$user_factory = UserFactory::getInstance();

এটি আপনাকে কী করতে বাধা দেয় (যা সিঙ্গলটন প্যাটার্ন লঙ্ঘন করে ..

তুমি এটি করতে পারবেনা!

$user_factory = UserFactory::$_instance;

class SecondUserFactory extends UserFactory { }

0

এটি সিঙ্গলটনের সঠিক পথ হওয়া উচিত।

class Singleton {

    private static $instance;
    private $count = 0;

    protected function __construct(){

    }

    public static function singleton(){

        if (!isset(self::$instance)) {

            self::$instance = new Singleton;

        }

        return self::$instance;

    }

    public function increment()
    {
        return $this->count++;
    }

    protected function __clone(){

    }

    protected function __wakeup(){

    }

} 

0

আমি @ জোস-সেগুরা বৈশিষ্ট্যগুলি ব্যবহারের পদ্ধতিটি পছন্দ করেছি তবে সাব-ক্লাসে স্থির পরিবর্তনশীল সংজ্ঞায়নের প্রয়োজন পছন্দ করি না। নীচে একটি সমাধান রয়েছে যা শ্রেণীর নাম অনুসারে সূচিত কারখানার পদ্ধতিতে স্থিতিশীল স্থানীয় চলকগুলিতে উদাহরণগুলি ক্যাশে করে এড়িয়ে চলে:

<?php
trait Singleton {

  # Single point of entry for creating a new instance. For a given
  # class always returns the same instance.
  public static function instance(){
    static $instances = array();
    $class = get_called_class();
    if( !isset($instances[$class]) ) $instances[$class] = new $class();
    return $instances[$class];
  }

  # Kill traditional methods of creating new instances
  protected function __clone() {}
  protected function __construct() {}
}

ব্যবহার যেমন @ জোসে-সেগুরার সমান, কেবলমাত্র সাব-ক্লাসে স্থির পরিবর্তনশীলের প্রয়োজন নেই।


0

ডাটাবেস ক্লাস যা পরীক্ষা করে যে কোনও বিদ্যমান ডাটাবেস উদাহরণ রয়েছে তা পূর্ববর্তী উদাহরণটি ফিরে আসবে।

   class Database {  
        public static $instance;  
         public static function getInstance(){  
            if(!isset(Database::$instance) ) {  
                Database::$instance = new Database();  
            }  
           return Database::$instance;  
         }  
         private function __cunstruct() {  
           /* private and cant create multiple objects */  
         }  
         public function getQuery(){  
            return "Test Query Data";  
         }  
    }  
    $dbObj = Database::getInstance();  
    $dbObj2 = Database::getInstance();  
    var_dump($dbObj);  
    var_dump($dbObj2);  


/* 
After execution you will get following output: 

object(Database)[1] 
object(Database)[1] 

*/  

রেফ http://www.phptechi.com/php-singleton-design-patterns-example.html


0

এটি ডাটাবেস ক্লাসে সিঙ্গেলটন তৈরির উদাহরণ

নকশা নিদর্শন 1) একক

class Database{
  public static $instance;
  public static function getInstance(){
    if(!isset(Database::$instance)){
    Database::$instance=new Database();

     return Database::$instance;
    }

  }

  $db=Database::getInstance();
  $db2=Database::getInstance();
  $db3=Database::getInstance();

  var_dump($db);
  var_dump($db2);
  var_dump($db3);

তারপর আউট করা হয় -

  object(Database)[1]
  object(Database)[1]
  object(Database)[1]

শুধুমাত্র একক উদাহরণ ব্যবহার করুন 3 উদাহরণ তৈরি করবেন না


0

দ্রুত উদাহরণ:

final class Singleton
{
    private static $instance = null;

    private function __construct(){}

    private function __clone(){}

    private function __wakeup(){}

    public static function get_instance()
    {
        if ( static::$instance === null ) {
            static::$instance = new static();
        }
        return static::$instance;
    }
}

সাহায্য আশা করি।


-4

এখানে আমার উদাহরণ যা $ var = নতুন সিঙ্গেলটন () হিসাবে কল করার ক্ষমতা প্রদান করে এবং এটি নতুন অবজেক্ট তৈরি করে কিনা তা পরীক্ষা করার জন্য 3 ভেরিয়েবল তৈরি করে:

class Singleton{

    private static $data;

    function __construct(){
        if ($this::$data == null){
            $this->makeSingleton();
        }
        echo "<br/>".$this::$data;
    }

    private function makeSingleton(){
        $this::$data = rand(0, 100);
    }

    public function change($new_val){
        $this::$data = $new_val;
    }

    public function printme(){
        echo "<br/>".$this::$data;
    }

}


$a = new Singleton();
$b = new Singleton();
$c = new Singleton();

$a->change(-2);
$a->printme();
$b->printme();

$d = new Singleton();
$d->printme();

5
এটি বাদে এটি সিঙ্গলটন নয়। আপনি একক ক্লাসের ক্লাসের একাধিক উদাহরণ তৈরি করতে পারেন।
অ্যান্ড্রু মুর

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

5
একটি সিঙ্গলটন এমন একটি বর্গ যা নিজের একটি মাত্র উদাহরণকে অনুমতি দেয়। একাধিক দৃষ্টান্ত তৈরি করে আপনি সেই নীতিটি অনুসরণ করছেন।
অ্যান্ড্রু মুর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.