मैं PHP 5 का उपयोग कर रहा हूं और मैंने ऑब्जेक्ट-ओरिएंटेड अप्रोच में एक नए फीचर के बारे में सुना है, जिसे 'मेथड चेनिंग' कहा जाता है। हकीकत में यह क्या है? मैं इसे कैसे लागू करूं?
मैं PHP 5 का उपयोग कर रहा हूं और मैंने ऑब्जेक्ट-ओरिएंटेड अप्रोच में एक नए फीचर के बारे में सुना है, जिसे 'मेथड चेनिंग' कहा जाता है। हकीकत में यह क्या है? मैं इसे कैसे लागू करूं?
जवाबों:
यह वास्तव में सरल है, आपके पास उत्परिवर्ती विधियों की एक श्रृंखला है जो सभी मूल (या अन्य) वस्तुओं को वापस करती है, इस तरह से आप लौटी हुई वस्तु पर कॉलिंग विधियों को रख सकते हैं।
<?php
class fakeString
{
private $str;
function __construct()
{
$this->str = "";
}
function addA()
{
$this->str .= "a";
return $this;
}
function addB()
{
$this->str .= "b";
return $this;
}
function getStr()
{
return $this->str;
}
}
$a = new fakeString();
echo $a->addA()->addB()->getStr();
यह "अब" आउटपुट
$foo->setBar(1)->setBaz(2)
बनाम $table->select()->from('foo')->where('bar = 1')->order('ASC)
। उत्तरार्द्ध कई वस्तुओं को फैलाता है।
$a = (new fakeString())->addA()->addB()->getStr();
मूल रूप से, आप एक वस्तु लेते हैं:
$obj = new ObjectWithChainableMethods();
एक विधि को कॉल करें जो प्रभावी रूप return $this;
से अंत में करता है :
$obj->doSomething();
चूँकि यह उसी वस्तु, या बल्कि, उसी वस्तु का संदर्भ देता है, आप रिटर्न मूल्य से उसी वर्ग के कॉलिंग तरीके जारी रख सकते हैं, जैसे:
$obj->doSomething()->doSomethingElse();
वास्तव में यही है। दो महत्वपूर्ण बातें:
जैसा कि आप ध्यान दें, यह केवल PHP 5 है। यह PHP 4 में ठीक से काम नहीं करेगा क्योंकि यह वस्तुओं को मूल्य से वापस करता है और इसका मतलब है कि आप किसी ऑब्जेक्ट की विभिन्न प्रतियों पर कॉल कर रहे हैं, जिससे आपका कोड टूट जाएगा।
फिर, आपको अपने श्रृंखला योग्य तरीकों में ऑब्जेक्ट को वापस करने की आवश्यकता है:
public function doSomething() {
// Do stuff
return $this;
}
public function doSomethingElse() {
// Do more stuff
return $this;
}
return &$this
PHP4 में कर सकते हैं ?
इस कोड को आज़माएं:
<?php
class DBManager
{
private $selectables = array();
private $table;
private $whereClause;
private $limit;
public function select() {
$this->selectables = func_get_args();
return $this;
}
public function from($table) {
$this->table = $table;
return $this;
}
public function where($where) {
$this->whereClause = $where;
return $this;
}
public function limit($limit) {
$this->limit = $limit;
return $this;
}
public function result() {
$query[] = "SELECT";
// if the selectables array is empty, select all
if (empty($this->selectables)) {
$query[] = "*";
}
// else select according to selectables
else {
$query[] = join(', ', $this->selectables);
}
$query[] = "FROM";
$query[] = $this->table;
if (!empty($this->whereClause)) {
$query[] = "WHERE";
$query[] = $this->whereClause;
}
if (!empty($this->limit)) {
$query[] = "LIMIT";
$query[] = $this->limit;
}
return join(' ', $query);
}
}
// Now to use the class and see how METHOD CHAINING works
// let us instantiate the class DBManager
$testOne = new DBManager();
$testOne->select()->from('users');
echo $testOne->result();
// OR
echo $testOne->select()->from('users')->result();
// both displays: 'SELECT * FROM users'
$testTwo = new DBManager();
$testTwo->select()->from('posts')->where('id > 200')->limit(10);
echo $testTwo->result();
// this displays: 'SELECT * FROM posts WHERE id > 200 LIMIT 10'
$testThree = new DBManager();
$testThree->select(
'firstname',
'email',
'country',
'city'
)->from('users')->where('id = 2399');
echo $testThree->result();
// this will display:
// 'SELECT firstname, email, country, city FROM users WHERE id = 2399'
?>
मेथड चेनिंग का मतलब है कि आप चेन मेथड कॉल कर सकते हैं:
$object->method1()->method2()->method3()
इसका मतलब यह है कि मेथड 1 () को एक ऑब्जेक्ट वापस करने की आवश्यकता है, और मेथड 2 () मेथड 1 () का परिणाम दिया गया है। Method2 () तब मेथड 3 () में रिटर्न वैल्यू पास करता है।
अच्छा लेख: http://www.talkphp.com/advanced-php-programming/1163-php5-method-chaining.html
class Maker
{
private static $result = null;
private static $delimiter = '.';
private static $data = [];
public static function words($words)
{
if( !empty($words) && count($words) )
{
foreach ($words as $w)
{
self::$data[] = $w;
}
}
return new static;
}
public static function concate($delimiter)
{
self::$delimiter = $delimiter;
foreach (self::$data as $d)
{
self::$result .= $d.$delimiter;
}
return new static;
}
public static function get()
{
return rtrim(self::$result, self::$delimiter);
}
}
echo Maker::words(['foo', 'bob', 'bar'])->concate('-')->get();
echo "<br />";
echo Maker::words(['foo', 'bob', 'bar'])->concate('>')->get();
कोड की 49 लाइनें हैं जो आपको इस तरह से सरणियों पर श्रृंखला विधियों की अनुमति देती हैं:
$fruits = new Arr(array("lemon", "orange", "banana", "apple"));
$fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key) {
echo $key.': '.$value."\r\n";
});
इस लेख को देखें जो आपको दिखाता है कि सभी PHP के सत्तर array_ फ़ंक्शन को कैसे चेन करें।
http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html
यदि आप जावास्क्रिप्ट में (या कुछ लोग jQuery को ध्यान में रखते हैं) की तरह विधि का मतलब है, तो बस एक पुस्तकालय क्यों नहीं है जो उस देव को लाता है। PHP में अनुभव? उदाहरण के लिए एक्स्ट्रा - https://dsheiko.github.io/extras/ यह जावास्क्रिप्ट और अंडरस्कोर विधियों के साथ PHP प्रकार का विस्तार करता है और चैनिंग प्रदान करता है:
आप एक विशेष प्रकार की श्रृंखला कर सकते हैं:
<?php
use \Dsheiko\Extras\Arrays;
// Chain of calls
$res = Arrays::chain([1, 2, 3])
->map(function($num){ return $num + 1; })
->filter(function($num){ return $num > 1; })
->reduce(function($carry, $num){ return $carry + $num; }, 0)
->value();
या
<?php
use \Dsheiko\Extras\Strings;
$res = Strings::from( " 12345 " )
->replace("/1/", "5")
->replace("/2/", "5")
->trim()
->substr(1, 3)
->get();
echo $res; // "534"
वैकल्पिक रूप से आप बहुरूपी जा सकते हैं:
<?php
use \Dsheiko\Extras\Any;
$res = Any::chain(new \ArrayObject([1,2,3]))
->toArray() // value is [1,2,3]
->map(function($num){ return [ "num" => $num ]; })
// value is [[ "num" => 1, ..]]
->reduce(function($carry, $arr){
$carry .= $arr["num"];
return $carry;
}, "") // value is "123"
->replace("/2/", "") // value is "13"
->then(function($value){
if (empty($value)) {
throw new \Exception("Empty value");
}
return $value;
})
->value();
echo $res; // "13"
नीचे मेरा मॉडल है जो डेटाबेस में आईडी द्वारा खोजने में सक्षम है। ($ डेटा) विधि के साथ मेरे रिश्ते के लिए अतिरिक्त पैरामीटर हैं, इसलिए मैं इस $ को वापस करता हूं जो कि स्वयं वस्तु है। अपने कंट्रोलर पर मैं इसे चेन करने में सक्षम हूं।
class JobModel implements JobInterface{
protected $job;
public function __construct(Model $job){
$this->job = $job;
}
public function find($id){
return $this->job->find($id);
}
public function with($data=[]){
$this->job = $this->job->with($params);
return $this;
}
}
class JobController{
protected $job;
public function __construct(JobModel $job){
$this->job = $job;
}
public function index(){
// chaining must be in order
$this->job->with(['data'])->find(1);
}
}