Saya menggunakan PHP 5 dan saya pernah mendengar tentang fitur baru dalam pendekatan berorientasi objek, yang disebut 'metode chaining'. Apa itu sebenarnya? Bagaimana cara menerapkannya?
Saya menggunakan PHP 5 dan saya pernah mendengar tentang fitur baru dalam pendekatan berorientasi objek, yang disebut 'metode chaining'. Apa itu sebenarnya? Bagaimana cara menerapkannya?
Jawaban:
Agaknya sederhana, Anda memiliki serangkaian metode mutator yang semuanya mengembalikan objek asli (atau lainnya), dengan begitu Anda dapat terus memanggil metode pada objek yang dikembalikan.
<?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();
Ini menghasilkan "ab"
$foo->setBar(1)->setBaz(2)
vs $table->select()->from('foo')->where('bar = 1')->order('ASC)
. Yang terakhir ini mencakup beberapa objek.
$a = (new fakeString())->addA()->addB()->getStr();
Pada dasarnya, Anda mengambil objek:
$obj = new ObjectWithChainableMethods();
Panggil metode yang secara efektif melakukan a return $this;
di akhir:
$obj->doSomething();
Karena mengembalikan objek yang sama, atau lebih tepatnya, referensi ke objek yang sama, Anda dapat melanjutkan memanggil metode dari kelas yang sama dari nilai pengembalian, seperti:
$obj->doSomething()->doSomethingElse();
Itu dia, sungguh. Dua hal penting:
Seperti yang Anda perhatikan, ini hanya PHP 5. Ini tidak akan berfungsi dengan baik di PHP 4 karena mengembalikan objek dengan nilai dan itu berarti Anda memanggil metode pada salinan objek yang berbeda, yang akan merusak kode Anda.
Sekali lagi, Anda perlu mengembalikan objek dalam metode yang dapat dilewati:
public function doSomething() {
// Do stuff
return $this;
}
public function doSomethingElse() {
// Do more stuff
return $this;
}
return &$this
di PHP4?
Coba kode ini:
<?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'
?>
Chaining metode berarti Anda dapat membuat panggilan metode panggilan:
$object->method1()->method2()->method3()
Ini berarti bahwa method1 () perlu mengembalikan objek, dan method2 () diberikan hasil dari method1 (). Method2 () kemudian meneruskan nilai kembali ke method3 ().
Artikel bagus: 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();
Ada 49 baris kode yang memungkinkan Anda untuk menghubungkan metode pada array seperti ini:
$fruits = new Arr(array("lemon", "orange", "banana", "apple"));
$fruits->change_key_case(CASE_UPPER)->filter()->walk(function($value,$key) {
echo $key.': '.$value."\r\n";
});
Lihat artikel ini yang menunjukkan kepada Anda bagaimana cara menghubungkan semua fungsi tujuh puluh array_ PHP.
http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html
Jika Anda maksud metode chaining seperti dalam JavaScript (atau beberapa orang mengingat jQuery), mengapa tidak mengambil perpustakaan yang membawa dev itu. pengalaman dalam PHP? Misalnya Ekstra - https://dsheiko.github.io/extras/ Yang ini memperluas jenis PHP dengan metode JavaScript dan Garis Bawah dan menyediakan rangkaian:
Anda dapat rantai jenis tertentu:
<?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();
atau
<?php
use \Dsheiko\Extras\Strings;
$res = Strings::from( " 12345 " )
->replace("/1/", "5")
->replace("/2/", "5")
->trim()
->substr(1, 3)
->get();
echo $res; // "534"
Atau Anda bisa menggunakan polimorfik:
<?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"
Di bawah ini adalah model saya yang dapat ditemukan oleh ID dalam database. Metode with ($ data) adalah parameter tambahan saya untuk hubungan jadi saya mengembalikan $ this yang merupakan objek itu sendiri. Pada pengontrol saya, saya dapat mengaitkannya.
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);
}
}