ฉันใช้ 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();
เอาท์พุตนี้ "ab"
$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()
นี่หมายความว่า method1 () ต้องส่งคืนออบเจ็กต์และ method2 () จะได้รับผลลัพธ์ของ method1 () วิธีที่ 2 () จากนั้นส่งผ่านค่าตอบแทนไปที่ method3 ()
บทความที่ดี: 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";
});
ดูบทความนี้ซึ่งแสดงวิธีการเชื่อมโยงฟังก์ชั่น array_ เจ็ดสิบของ PHP ทั้งหมด
http://domexception.blogspot.fi/2013/08/php-magic-methods-and-arrayobject.html
หากคุณหมายถึงวิธีการผูกมัดเช่นใน JavaScript (หรือบางคนจำ jQuery) ทำไมไม่ใช้ห้องสมุดที่นำ dev นั้น มีประสบการณ์เกี่ยวกับ PHP ไหม? ตัวอย่างเช่น Extras - https://dsheiko.github.io/extras/ อันนี้จะขยายประเภท PHP ด้วย JavaScript และวิธีขีดล่างและให้การผูกมัด:
คุณสามารถโยงประเภทเฉพาะ:
<?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"
หรือคุณสามารถไป polymorphic:
<?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"
ด้านล่างเป็นรุ่นของฉันที่สามารถค้นหาด้วย ID ในฐานข้อมูล เมธอด with ($ data) เป็นพารามิเตอร์เพิ่มเติมของฉันสำหรับความสัมพันธ์ดังนั้นฉันจึงส่งกลับ $ this ซึ่งเป็นวัตถุ บนตัวควบคุมของฉันฉันสามารถโยงมันได้
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);
}
}