আমি কীভাবে পিএইচপিতে কলব্যাক প্রয়োগ করব?


উত্তর:


173

ম্যানুয়ালটি "কলব্যাক" এবং "কলযোগ্য" পদটি আন্তঃবিন্যস্তভাবে ব্যবহার করে, তবে, "কলব্যাক" traditionতিহ্যগতভাবে একটি স্ট্রিং বা অ্যারের মানকে বোঝায় যা ফাংশন পয়েন্টারের মতো কাজ করে , ভবিষ্যতের অনুরোধের জন্য কোনও ফাংশন বা শ্রেণি পদ্ধতি উল্লেখ করে। এটি পিএইচপি 4 সাল থেকে কার্যকরী প্রোগ্রামিংয়ের কিছু উপাদানকে অনুমতি দিয়েছে The স্বাদগুলি হ'ল:

$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];

// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error

// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');

সাধারণভাবে কলযোগ্য মানগুলি ব্যবহারের এটি একটি নিরাপদ উপায়:

if (is_callable($cb2)) {
    // Autoloading will be invoked to load the class "ClassName" if it's not
    // yet defined, and PHP will check that the class has a method
    // "someStaticMethod". Note that is_callable() will NOT verify that the
    // method can safely be executed in static context.

    $returnValue = call_user_func($cb2, $arg1, $arg2);
}

আধুনিক পিএইচপি সংস্করণগুলি উপরের প্রথম তিনটি ফর্ম্যাটগুলিকে সরাসরি অনুরোধ করার অনুমতি দেয় $cb()call_user_funcএবং call_user_func_arrayউপরের সমস্ত সমর্থন।

দেখুন: http://php.net/manual/en/language.tyype.callable.php

নোট / আদেশ সহকারে:

  1. যদি ফাংশন / শ্রেণিটির নাম স্পেস হয় তবে স্ট্রিংটিতে অবশ্যই পূর্ণ-যোগ্যতাসম্পন্ন নাম থাকতে হবে। যেমন['Vendor\Package\Foo', 'method']
  2. call_user_func, রেফারেন্স দ্বারা অ বস্তু ক্ষণস্থায়ী যাতে আপনি পারেন ব্যবহার করতে পারেন সমর্থন করে না call_user_func_arrayএকটি Var অথবা পরে পিএইচপি সংস্করণে, কলব্যাক সংরক্ষণ এবং সরাসরি সিনট্যাক্স ব্যবহার করুন: $cb();
  3. কোনও পদ্ধতিযুক্ত অবজেক্টগুলি __invoke()(বেনামে ফাংশন সহ) "কলযোগ্য" বিভাগের অধীনে আসে এবং একইভাবে ব্যবহার করা যেতে পারে, তবে আমি ব্যক্তিগতভাবে এগুলি লিগ্যাসির "কলব্যাক" শব্দটির সাথে যুক্ত করি না।
  4. উত্তরাধিকার create_function()একটি বিশ্বব্যাপী ফাংশন তৈরি করে এবং এর নাম ফিরিয়ে দেয়। এটি এর জন্য একটি মোড়ক eval()এবং এর পরিবর্তে বেনামী ফাংশন ব্যবহার করা উচিত।

আসলে, ফাংশনটি ব্যবহার করা এটি করার সঠিক উপায় way কোনও ভেরিয়েবল ব্যবহার করার পরে এবং কেবল এটির কল করার সময়, যেমন গৃহীত উত্তরের পরামর্শ দেওয়া হয়েছে তা দুর্দান্ত, এটি কুরুচিপূর্ণ এবং কোড সহ ভাল স্কেল করবে না।
আইকো

4
গৃহীত উত্তর পরিবর্তন করা হয়েছে। মন্তব্য সহ একমত, এটি একটি দুর্দান্ত উত্তর।
নিক স্টিনিমেটস

পাইথন প্রোগ্রামিং থেকে আগত পাঠকদের পক্ষে উত্তরের জন্য যে 'someGlobalFunction'এটি একটি সংজ্ঞায়িত ফাংশন , তা উল্লেখ করতে সহায়ক হবে ।
TMOTTM

1
পিএইচপি 5.3 হিসাবে, বন্ধ রয়েছে, বার্ট ভ্যান হিউকেলোমের উত্তর দেখুন । এই সমস্ত উত্তরাধিকারসূত্রে জঞ্জালের চেয়ে এটি অনেক সহজ এবং "স্ট্যান্ডার্ড"।
সত্যই চমৎকার

হ্যাঁ, আমি আমার উত্তরে বেনামে ফাংশনগুলি উল্লেখ করেছি, তবে ওপি "কলব্যাক" চেয়েছিল (২০০৮ সালে) এবং এই পুরানো শৈলীর কলব্যাকগুলি এখনও টন পিএইচপি কোডবেসগুলিতে ব্যবহৃত হচ্ছে।
স্টিভ ক্লে

74

পিএইচপি 5.3 এর সাহায্যে আপনি এখন এটি করতে পারেন:

function doIt($callback) { $callback(); }

doIt(function() {
    // this will be done
});

অবশেষে এটি করার একটি দুর্দান্ত উপায়। পিএইচপি-তে একটি দুর্দান্ত সংযোজন, কারণ কলব্যাকগুলি দুর্দান্ত।


1
এটি শীর্ষ উত্তর হতে হবে।
গ্রোয়ার

30

কলব্যাকের বাস্তবায়ন যেমন হয়

// This function uses a callback function. 
function doIt($callback) 
{ 
    $data = "this is my data";
    $callback($data); 
} 


// This is a sample callback function for doIt(). 
function myCallback($data) 
{ 
    print 'Data is: ' .  $data .  "\n"; 
} 


// Call doIt() and pass our sample callback function's name. 
doIt('myCallback');

প্রদর্শন: ডেটা হ'ল এটি আমার ডেটা


21
হে ভগবান. এটা কি স্ট্যান্ডার্ড? ভয়ানক!
নিক retallack

এটি করার মতো আরও কয়েকটি উপায় রয়েছে যা উপরের মত দেখানো হয়েছে। আমি সত্যিই একই চিন্তা।
নিক স্টিনিমেটস

3
@ নিক রেটাল্যাক, আমি এটিকে কী ভয়ংকর তা দেখছি না। আমি যে ভাষাগুলি জানি, যেমন জাভাস্ক্রিপ্ট এবং সি # এর জন্য তারা সকলেই তাদের কলব্যাক ফাংশনটিকে এ জাতীয় প্যাটার্নে গঠন করতে পারে। জাভাস্ক্রিপ্ট এবং সি # থেকে আগত, আমি সত্যিই কল_উজার_ফুন () কল করতে অভ্যস্ত নই। এটি আমার মনে করে যে আমাকে অন্য চারপাশের পরিবর্তে পিএইচপি-র সাথে নিজেকে খাপ খাইয়ে নিতে হবে।
অ্যান্টনি

4
@ অ্যান্টনি আমি এই বিষয়টি নিয়ে আপত্তি জানিয়েছিলাম যে স্ট্রিংগুলি এই ভাষায় ফাংশন পয়েন্টার। আমি এই মন্তব্যটি তিন বছর আগে পোস্ট করেছি, সুতরাং এখনই আমি এটির বেশ অভ্যস্ত, তবে আমি মনে করি পিএইচপি হ'ল আমি জানি এমন একমাত্র ভাষা (শেল স্ক্রিপ্টিং ব্যতীত) যেখানে এই ঘটনাটি রয়েছে।
নিক retallack

1
@ অ্যান্টনি আমি জাভাস্ক্রিপ্টে আমি একই সিনট্যাক্স ব্যবহার করতে পছন্দ করি। সুতরাং আমি এমনকি বুঝতে পারছি না যে লোকেরা call_user_func()যখন এমন একটি সিনট্যাক্স ব্যবহার করতে চায় যা তাদের ডায়নামিকভাবে ফাংশনগুলি কল করতে এবং কলব্যাক করতে সক্ষম করে। আমি আপনার সাথে একমত!
বোটেনউউউয়ার

9

একটি নিফটি ট্রিক যা আমি সম্প্রতি খুঁজে পেয়েছি তা হল পিএইচপি create_function()ব্যবহার করে এক শট ব্যবহারের জন্য বেনামে / ল্যাম্বদা ফাংশন তৈরি করতে। মনে হচ্ছে পিএইচপি কাজকর্মের জন্য উপযোগী array_map(), preg_replace_callback()অথবা usort()কাস্টম প্রক্রিয়াকরণের জন্য ব্যবহারের callbacks। এটি দেখতে অনেকটা দেখতে দেখতে eval()এটি কভারগুলির নীচে করে তবে এটি পিএইচপি ব্যবহারের জন্য এখনও একটি দুর্দান্ত কার্যকরী-শৈলীর উপায়।


6
দুর্ভাগ্যক্রমে, আবর্জনা সংগ্রহকারী এই সম্ভাব্য মেমরি ফাঁস উত্পাদন করে খুব ভাল খেলে না। আপনি যদি পারফরম্যান্সের জন্য বাইরে থাকেন তবে create_function () এড়িয়ে চলুন।
ফুসিয়া

1
সেকি। সতর্ক থাকুন জন্য ধন্যবাদ.
ইউকনডুড

আপনার কি পিএইচপি 7.4 সংস্করণ (তীর ফাংশন) দিয়ে উত্তর আপডেট করে এবং অবহসিত সম্পর্কে একটি সতর্কতা যুক্ত করতে আপত্তি হবে create_function()?
ধর্মমান

7

ঠিক আছে ... দিগন্তের 5.3 এর সাথে সমস্ত কিছু ভাল হবে, কারণ 5.3 এর সাথে আমরা ক্লোজার পেয়ে যাব এবং তাদের সাথে বেনামে ফাংশন করব

http://wiki.php.net/rfc/closures


7

আপনার কলিং যা বৈধ তা আপনি যাচাই করতে চাইবেন। উদাহরণস্বরূপ, একটি নির্দিষ্ট ফাংশনের ক্ষেত্রে, আপনি পরীক্ষা করতে পারেন এবং ফাংশনটি বিদ্যমান কিনা তা দেখতে চাইবেন:

function doIt($callback) {
    if(function_exists($callback)) {
        $callback();
    } else {
        // some error handling
    }
}

কলব্যাক যদি কোনও ফাংশন না হয় তবে অ্যারে হোল্ডিং অবজেক্ট এবং পদ্ধতি হয়?
d -_- বি

3
বা বরংis_callable( $callback )
রোকো সি বুলজান

1
উভয়ই ভাল পরামর্শ - আপনি কীভাবে কলব্যাক করবেন তার নিজস্ব নির্দিষ্ট বাস্তবায়ন পরীক্ষা করা প্রয়োজন। আমি এমন কিছু কল করার বিরুদ্ধে সতর্ক করার প্রত্যাশা করছিলাম যা মারাত্মক কারণ হিসাবে উপস্থিত ছিল না। আমি উত্তরটি আরও সাধারণ করে
দিয়েছি

5

create_functionআমার জন্য কোনও ক্লাসের মধ্যে কাজ করেনি। আমাকে ব্যবহার করতে হয়েছিল call_user_func

<?php

class Dispatcher {
    //Added explicit callback declaration.
    var $callback;

    public function Dispatcher( $callback ){
         $this->callback = $callback;
    }

    public function asynchronous_method(){
       //do asynch stuff, like fwrite...then, fire callback.
       if ( isset( $this->callback ) ) {
            if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
        }
    }

}

তারপরে, ব্যবহার করতে:

<?php 
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();

function do_callback( $data ){
   print 'Data is: ' .  $data .  "\n";
}
?>

[সম্পাদনা] একটি অনুপস্থিত প্রথম বন্ধনী যুক্ত হয়েছে। এছাড়াও, কলব্যাকের ঘোষণাটি যুক্ত করা হয়েছে, আমি সেভাবেই এটি পছন্দ করি।


1
ডিসপ্যাচার ক্লাসে কাজ করার জন্য $ এই-> কলব্যাক = $ কলব্যাকের জন্য কোনও গুনের প্রয়োজন নেই?
জেমস পি।

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

আমি জানতাম না এটি সম্ভব ছিল। উত্তর করার জন্য ধন্যবাদ :) .
জেমস পি।

ডিসপ্যাচার অবজেক্ট তৈরি করার আগে এবং অ্যাসিঙ্ক পদ্ধতিটি কল করার আগে do_callback ফাংশনটি ঘোষণা করা কি নিরাপদ নয়?
ইজেক্টমেন্ট

3

আমি create_function()পিএইচপি ব্যবহারের সময় প্রতিবার ক্রিঙ্ক করি ।

প্যারামিটারগুলি একটি কোমা দ্বারা পৃথক স্ট্রিং, একটি স্ট্রিংয়ের পুরো ফাংশন বডি ... আরগ ... আমি মনে করি তারা চেষ্টা করলেও তারা এটিকে আরও খারাপ করতে পারত না।

দুর্ভাগ্যক্রমে, এটি একমাত্র পছন্দ যখন কোনও নামযুক্ত ফাংশন তৈরি করা ঝামেলার পক্ষে নয়।


1
এবং, অবশ্যই এটি রানটাইম স্ট্রিং al
হাবস

এই উত্তরটি গত 2 বছর ধরে পুরানো। create_function()এখন অবহেলিত এবং ব্যবহার করা উচিত নয়।
ধর্মান

2

যারা পিএইচপি-র সাথে সামঞ্জস্যতা ভঙ্গ করার বিষয়ে চিন্তা করেন না তাদের জন্য < 5.4আমি ক্লিনারটি বাস্তবায়ন করতে টাইপ ইঙ্গিতটি ব্যবহার করার পরামর্শ দেব।

function call_with_hello_and_append_world( callable $callback )
{
     // No need to check $closure because of the type hint
     return $callback( "hello" )."world";
}

function append_space( $string )
{
     return $string." ";
}

$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"

$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"

$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"

সতর্কতা create_function() পিএইচপি 7.2.0 হিসাবে অবহিত করা হয়েছে। এই ফাংশন উপর নির্ভর করা অত্যন্ত নিরুৎসাহিত করা হয়।
ধর্মান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.