একটি পিএইচপি অ্যাপ্লিকেশন জন্য প্লাগইন অনুমোদন করার শ্রেষ্ঠ উপায়

আমি একটি নতুন ওয়েব অ্যাপ্লিকেশন শুরু করছি পিএইচপি এবং এই সময় কাছাকাছি আমি একটি প্লাগইন ইন্টারফেস ব্যবহার করে মানুষ প্রসারিত করতে পারেন যে কিছু তৈরি করতে চান

কিভাবে একটি 'hooks' লিখতে সম্পর্কে তাদের কোডে না যাতে প্লাগইন নির্দিষ্ট ঘটনা সংযুক্ত করতে পারেন?

0
যোগ সম্পাদিত
মতামত: 7

8 উত্তর

আপনি একটি পর্যবেক্ষক প্যাটার্ন ব্যবহার করতে পারে। এটি সম্পন্ন করার একটি সহজ কার্যকরী উপায়:

<?php

/** Plugin system **/

$listeners = array();

/* Create an entry point for plugins */
function hook() {
    global $listeners;

    $num_args = func_num_args();
    $args = func_get_args();

    if($num_args < 2)
        trigger_error("Insufficient arguments", E_USER_ERROR);

    // Hook name should always be first argument
    $hook_name = array_shift($args);

    if(!isset($listeners[$hook_name]))
        return; // No plugins have registered this hook

    foreach($listeners[$hook_name] as $func) {
        $args = $func($args); 
    }
    return $args;
}

/* Attach a function to a hook */
function add_listener($hook, $function_name) {
    global $listeners;
    $listeners[$hook][] = $function_name;
}

/////////////////////////

/** Sample Plugin **/
add_listener('a_b', 'my_plugin_func1');
add_listener('str', 'my_plugin_func2');

function my_plugin_func1($args) {
    return array(4, 5);
}

function my_plugin_func2($args) {
    return str_replace('sample', 'CRAZY', $args[0]);
}

/////////////////////////

/** Sample Application **/

$a = 1;
$b = 2;

list($a, $b) = hook('a_b', $a, $b);

$str  = "This is my sample application\n";
$str .= "$a + $b = ".($a+$b)."\n";
$str .= "$a * $b = ".($a*$b)."\n";

$str = hook('str', $str);
echo $str;
?>

এ আউটপুট:

This is my CRAZY application
4 + 5 = 9
4 * 5 = 20

এ নোট:

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

এই পিএইচপি একটি প্লাগইন সিস্টেম সম্পন্ন মাত্র এক পদ্ধতি। আরও ভাল বিকল্প আছে, আমি সুপারিশ আরও তথ্যের জন্য ওয়ার্ডপ্রেস ডকুমেন্টেশন।

দুঃখিত, এটি মার্কডাউন দ্বারা HTML অক্ষর দ্বারা প্রতিস্থাপিত অক্ষরের অক্ষর প্রদর্শিত হয়? এই বাগ ঠিক হলে আমি এই কোডটি পুনরায় পোস্ট করতে পারি।

সম্পাদনা করুন: কিছুই চিন্তা করবেন না, এটি শুধুমাত্র যখন আপনি সম্পাদনা করছেন এভাবেই প্রদর্শিত হবে

0
যোগ
Pedantic নোট: এই পর্যবেক্ষক প্যাটার্ন একটি উদাহরণ নয়। এটি মধ্যবর্তী প্যাটার্ন </ কোড> এর একটি উদাহরণ। সত্য পর্যবেক্ষক সম্পূর্ণরূপে বিজ্ঞপ্তি, কোন বার্তা পাসিং বা শর্তাধীন বিজ্ঞপ্তি (বা নিয়ামক নিয়ন্ত্রণের জন্য একটি কেন্দ্রীয় ব্যবস্থাপক নেই) আছে এটা ভুল উত্তর দেয় না, তবে ভুল নাম দিয়ে লোকেরা কল করার জন্য এটি বন্ধ করা উচিত বলে মনে করা উচিত ...
যোগ লেখক ircmaxell, উৎস
লক্ষ্য করুন যে পিএইচপি> = 5.0 এর জন্য আপনি এসপিএল-তে নির্ধারিত অবজার্ভার / বিষয় ইন্টারফেস ব্যবহার করে এটি প্রয়োগ করতে পারেন: php.net/manual/en/class.splobserver.php
যোগ লেখক John Carter, উৎস
লক্ষ্য করুন যে যখন একাধিক হুক / শ্রোতার ব্যবহার করা হয়, তখন আপনাকে কেবল স্ট্রিং বা অ্যারে ফেরত দেওয়া উচিত নয়, উভয়ই নয়। আমি হাউন্ড সিএমএস এর অনুরূপ কিছু প্রয়োগ করেছি - getbutterfly.com/hound
যোগ লেখক Ciprian, উৎস

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

kdeloach একটি চমৎকার উদাহরণ আছে, কিন্তু তার বাস্তবায়ন এবং হুক ফাংশন একটি সামান্য অনিরাপদ। আমি আপনার পিএইচপি অ্যাপ্লিকেশন আপনার লেখার প্রকৃতি সম্পর্কে আরো তথ্য দিতে চাইতে হবে, এবং কিভাবে আপনি plugins ফিটিং দেখতে।

+1 আমার কাছ থেকে kdeloach

0
যোগ

আমি বিশ্বাস করি যে সবচেয়ে সহজ উপায় জাফ এর নিজের পরামর্শ অনুসরণ করা হবে এবং বিদ্যমান কোড কাছাকাছি একটি চেহারা আছে। ওয়ার্ডপ্রেস, ড্রুপাল, জুমলা এবং অন্যান্য সুপরিচিত পিএইচপি-ভিত্তিক সিএমএস এর দিকে তাকানোর জন্য দেখুন কিভাবে তাদের API হুক চেহারা এবং অনুভূতি। এই ভাবে আপনি এমনকি ধারণা পেতে পারেন আপনি পূর্বে কিছু চিন্তা করতে পারে না কিছু rubid করতে।

আরো সরাসরি উত্তর লিখতে হবে যে তাদের ফাইলের মধ্যে "include_once" লিখতে হবে যেগুলি তাদের প্রয়োজনে ব্যবহারযোগ্যতা প্রদান করবে। এটি একটি ব্যাপক "hooks.php" ফাইলের মধ্যে শ্রেণিতে বিভক্ত এবং না দেওয়া হবে। যদিও সতর্কতা অবলম্বন করা উচিত, কারণ কি ঘটছে শেষ হয় যে তারা আরো এবং আরো নির্ভরতা এবং কার্যকারিতা উন্নতি করে শেষ অন্তর্ভুক্ত ফাইল এপিআই নির্ভরতা কম রাখতে চেষ্টা করুন তাদের জন্য অন্তর্ভুক্ত কয়েকটি ফাইল।

0
যোগ
আমি DokuWiki কে আপনার সিস্টেমে তালিকাভুক্ত করতে চাই। এটি একটি চমৎকার ইভেন্ট সিস্টেম যা একটি সমৃদ্ধ প্লাগইন ইকোসিস্টেমের জন্য অনুমোদিত।
যোগ লেখক chiborg, উৎস

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

<?php

////////////////////
// PART 1
////////////////////

class Plugin {

    private $_RefObject;
    private $_Class = '';

    public function __construct(&$RefObject) {
        $this->_Class = get_class(&$RefObject);
        $this->_RefObject = $RefObject;
    }

    public function __set($sProperty,$mixed) {
        $sPlugin = $this->_Class . '_' . $sProperty . '_setEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }   
        $this->_RefObject->$sProperty = $mixed;
    }

    public function __get($sProperty) {
        $asItems = (array) $this->_RefObject;
        $mixed = $asItems[$sProperty];
        $sPlugin = $this->_Class . '_' . $sProperty . '_getEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }   
        return $mixed;
    }

    public function __call($sMethod,$mixed) {
        $sPlugin = $this->_Class . '_' .  $sMethod . '_beforeEvent';
        if (is_callable($sPlugin)) {
            $mixed = call_user_func_array($sPlugin, $mixed);
        }
        if ($mixed != 'BLOCK_EVENT') {
            call_user_func_array(array(&$this->_RefObject, $sMethod), $mixed);
            $sPlugin = $this->_Class . '_' . $sMethod . '_afterEvent';
            if (is_callable($sPlugin)) {
                call_user_func_array($sPlugin, $mixed);
            }       
        } 
    }

} //end class Plugin

class Pluggable extends Plugin {
} //end class Pluggable

////////////////////
// PART 2
////////////////////

class Dog {

    public $Name = '';

    public function bark(&$sHow) {
        echo "$sHow
\n"; } public function sayName() { echo "
\nMy Name is: " . $this->Name . "
\n"; } } //end class Dog $Dog = new Dog(); //////////////////// // PART 3 //////////////////// $PDog = new Pluggable($Dog); function Dog_bark_beforeEvent(&$mixed) { $mixed = 'Woof'; // Override saying 'meow' with 'Woof' //$mixed = 'BLOCK_EVENT'; // if you want to block the event return $mixed; } function Dog_bark_afterEvent(&$mixed) { echo $mixed; // show the override } function Dog_Name_setEvent(&$mixed) { $mixed = 'Coco'; // override 'Fido' with 'Coco' return $mixed; } function Dog_Name_getEvent(&$mixed) { $mixed = 'Different'; // override 'Coco' with 'Different' return $mixed; } //////////////////// // PART 4 //////////////////// $PDog->Name = 'Fido'; $PDog->Bark('meow'); $PDog->SayName(); echo 'My New Name is: ' . $PDog->Name;

পার্ট 1 এ, আপনার পিএইচপি স্ক্রিপ্টের শীর্ষে need_once() কল সহ আপনি কি অন্তর্ভুক্ত হতে পারে? প্ল্যাগেবল কিছু করার জন্য ক্লাসগুলি লোড করে।

পার্ট ২ তে, যেখানে আমরা একটি ক্লাস লোড করি। উল্লেখ্য, আমি ক্লাসে বিশেষ কিছু করার প্রয়োজন ছিল না, যা পর্যবেক্ষক প্যাটার্নের চেয়ে উল্লেখযোগ্যভাবে ভিন্ন।

3 অংশে, যেখানে আমরা আমাদের শ্রেণীকে প্রায় "প্ল্যাগেবল" (অর্থাৎ, প্লাগইন সমর্থন করে যা আমাদের ক্লাসের পদ্ধতি এবং বৈশিষ্ট্যগুলিকে ওভাররাইড করে দেয়) এ পরিণত করে। উদাহরণস্বরূপ, উদাহরণস্বরূপ, যদি আপনার কোনও ওয়েব অ্যাপ্লিকেশন থাকে, তাহলে আপনার কাছে একটি প্লাগইন রেজিস্ট্রি থাকতে পারে, এবং আপনি এখানে প্লাগইন সক্রিয় করতে পারেন। এছাড়াও Dog_bark_beforeEvent() ফাংশন লক্ষ্য করুন। যদি আমি রিটার্ন স্টেটমেন্টের আগে $ mixed = 'BLOCK_EVENT' সেট করি, তাহলে কুকুরকে বক্রিং থেকে আটকানো হবে এবং কুকুরটি বন্ধ করার পরেও কোনও ইভেন্টটি থাকবে না।

4 অংশে, এটি স্বাভাবিক অপারেশন কোড, কিন্তু লক্ষ্য করুন যে আপনি যা চালাতে পারেন তা মনে হতে পারে যেমনটি চলবে না। উদাহরণস্বরূপ, কুকুরটি 'ফিডো' নামে এটির নাম ঘোষণা করে না, তবে 'কোকো'। কুকুর 'ম্যুপ' বলে না, কিন্তু 'ওয়োফ' এবং আপনি পরে কুকুর এর নাম তাকান করতে চান, আপনি 'কোকো' এর পরিবর্তে 'ভিন্ন' এটি খুঁজে। যারা সমস্ত overrides অংশ 3 প্রদান করা হয়।

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

0
যোগ
আমি এই বিষয়ে উইকিপিডিয়া পড়ি এবং, হে, আপনি ঠিক! :)
যোগ লেখক Volomike, উৎস
এই একটি শোভাকর না?
যোগ লেখক MV., উৎস

এখানে একটি পদ্ধতি যা আমি ব্যবহার করেছি, এটি Qt সিগন্যাল / স্লট প্রক্রিয়া থেকে অনুলিপি করার একটি প্রচেষ্টা, একটি পর্যবেক্ষক প্যাটার্ন। অবজেক্টগুলি সংকেত নির্গত হতে পারে। প্রতিটি সংকেত সিস্টেমে একটি আইডি আছে - এটি প্রেরকের আইডি + অবজেক্টের নাম দ্বারা গঠিত প্রতিটি সংকেত রিসিভারের সাথে বাঁধা হতে পারে, যা কেবল একটি "কলযোগ্য" আপনি তাদের প্রাপ্তিতে আগ্রহী যে কেউ সিগন্যাল প্রেরণ করতে একটি বাস ক্লাস ব্যবহার কিছু ঘটে যখন, আপনি একটি সংকেত "পাঠাতে" নীচে এবং উদাহরণ বাস্তবায়ন হয়

    <?php

class SignalsHandler {


    /**
     * hash of senders/signals to slots
     *
     * @var array
     */
    private static $connections = array();


    /**
     * current sender
     *
     * @var class|object
     */
    private static $sender;


    /**
     * connects an object/signal with a slot
     *
     * @param class|object $sender
     * @param string $signal
     * @param callable $slot
     */
    public static function connect($sender, $signal, $slot) {
        if (is_object($sender)) {
            self::$connections[spl_object_hash($sender)][$signal][] = $slot;
        }
        else {
            self::$connections[md5($sender)][$signal][] = $slot;
        }
    }


    /**
     * sends a signal, so all connected slots are called
     *
     * @param class|object $sender
     * @param string $signal
     * @param array $params
     */
    public static function signal($sender, $signal, $params = array()) {
        self::$sender = $sender;
        if (is_object($sender)) {
            if ( ! isset(self::$connections[spl_object_hash($sender)][$signal])) {
                return;
            }
            foreach (self::$connections[spl_object_hash($sender)][$signal] as $slot) {
                call_user_func_array($slot, (array)$params);
            }

        }
        else {
            if ( ! isset(self::$connections[md5($sender)][$signal])) {
                return;
            }
            foreach (self::$connections[md5($sender)][$signal] as $slot) {
                call_user_func_array($slot, (array)$params);
            }
        }

        self::$sender = null;
    }


    /**
     * returns a current signal sender
     *
     * @return class|object
     */
    public static function sender() {
        return self::$sender;
    }

}   

class User {

    public function login() {
        /**
         * try to login
         */
        if ( ! $logged ) {
            SignalsHandler::signal(this, 'loginFailed', 'login failed - username not valid' );
        }
    }

}

class App {
    public static function onFailedLogin($message) {
        print $message;
    }
}


$user = new User();
SignalsHandler::connect($user, 'loginFailed', array($Log, 'writeLog'));
SignalsHandler::connect($user, 'loginFailed', array('App', 'onFailedLogin'));

$user->login();

?>
0
যোগ

আমি আশ্চর্য হচ্ছি যে অধিকাংশ উত্তর এখানে প্লাগইন সম্পর্কে জাগ্রত বলে মনে হচ্ছে যে ওয়েব অ্যাপ্লিকেশনের স্থানীয়, অর্থাৎ, স্থানীয় ওয়েব সার্ভারে চালানো প্লাগইনগুলি।

যদি আপনি একটি ভিন্ন - প্লাগইন চালানোর জন্য চেয়েছিলেন - কি - সার্ভার? এটি করার সর্বোত্তম উপায় হল একটি ফর্ম প্রদান করা যা আপনাকে আপনার ইউজারদেরকে নির্দিষ্ট অ্যাপ্লিকেশনগুলি যখন আপনার অ্যাপ্লিকেশনে ঘটানো হবে তখন বিভিন্ন URL সংজ্ঞায়িত করতে অনুমতি দেবে।

বিভিন্ন ঘটনা ঘটতে পারে এমন ঘটনার উপর ভিত্তি করে বিভিন্ন তথ্য পাঠাবে।

এই ভাবে, আপনি কেবল আপনার অ্যাপ্লিকেশন (যেমন https- এর মতো) প্রদান করা হয়েছে এমন URL তে একটি curl কল করবেন যেখানে দূরবর্তী সার্ভার আপনার অ্যাপ্লিকেশন দ্বারা পাঠানো তথ্যের উপর ভিত্তি করে কাজগুলি করতে পারে।

এটি দুটি সুবিধা প্রদান করে:

  1. আপনার স্থানীয় সার্ভারে কোন কোড হোস্ট করতে হবে না (নিরাপত্তা)
  2. কোডটি দূরবর্তী সার্ভারে (extensibility) হতে পারে অন্য ভাষায় পিএইচপি (পোর্টেবিলিটি) অন্যান্য ভাষায়
0
যোগ
এটি একটি "প্লাগইন" সিস্টেমের তুলনায় "ধাক্কা API" এর বেশি - আপনি অন্যান্য ইভেন্টগুলির জন্য নির্বাচিত ইভেন্টগুলির বিজ্ঞপ্তি পেতে একটি উপায় প্রদান করছেন। সাধারণত "প্লাগইনগুলি" দ্বারা বোঝানো হয় যে আপনি অ্যাপ্লিকেশনটি ইনস্টল করতে পারেন এবং তার কার্যকারিতা কাস্টমাইজ করতে আপনার কার্যকারিতা কাস্টমাইজ করতে পারেন, যার জন্য প্লাগইনটি স্থানীয়ভাবে চলতে হবে - অথবা কমপক্ষে একটি নিরাপদ ও কার্যকর 2-উপায় যোগাযোগের ব্যবস্থা করতে হবে তথ্য থেকে অ্যাপ্লিকেশনটি কেবল এটি থেকে গ্রহণ করে না দুটি বৈশিষ্ট্যগুলি কিছুটা স্বতন্ত্র, এবং অনেক ক্ষেত্রে একটি "ফিড" (যেমন, আরএসএস, আইসিএল) একটি ধাক্কা API
যোগ লেখক IMSoP, উৎস

ইয়াহুতে ম্যাট জান্ড্রাস্টা দ্বারা স্টিকব্যাক নামক একটি সুশৃঙ্খল প্রকল্প রয়েছে যা পরিচালনা করে পিএইচপি মধ্যে প্লাগইন পরিচালনার জন্য অনেক কাজ

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

0
যোগ

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

জেন্ড ফ্রেমওয়ার্ক অনেক হুকিং পদ্ধতি ব্যবহার করে এবং এটি খুব সুন্দরভাবে নির্মিত। এটি দেখতে একটি ভাল সিস্টেম হতে হবে।

0
যোগ