สิ่งที่ฉันต้องการจะทำมีดังนี้:
$method_result = new Obj()->method();
แทนที่จะต้องทำ:
$obj = new Obj();
$method_result = $obj->method();
ผลลัพธ์ที่ได้ไม่สำคัญสำหรับฉันในกรณีเฉพาะของฉัน แต่มีวิธีทำหรือไม่?
my_methodควรจะประกาศแทนstaticหรือไม่
สิ่งที่ฉันต้องการจะทำมีดังนี้:
$method_result = new Obj()->method();
แทนที่จะต้องทำ:
$obj = new Obj();
$method_result = $obj->method();
ผลลัพธ์ที่ได้ไม่สำคัญสำหรับฉันในกรณีเฉพาะของฉัน แต่มีวิธีทำหรือไม่?
my_methodควรจะประกาศแทนstaticหรือไม่
คำตอบ:
คุณลักษณะที่คุณขอมีให้จาก PHP 5.4 นี่คือรายการคุณสมบัติใหม่ใน PHP 5.4:
http://php.net/manual/en/migration54.new-features.php
และส่วนที่เกี่ยวข้องจากรายการคุณสมบัติใหม่:
มีการเพิ่มการเข้าถึงของสมาชิกชั้นเรียนในการสร้างอินสแตนซ์เช่น (Foo ใหม่) -> bar ()
(new Foo)->propertyหากต้องการ
(new Foo)->property- ค่าที่คุณจัดเก็บไม่มีที่ไปเพราะวัตถุจะไม่มีอยู่อีกต่อไปหลังจากนั้นเนื่องจากไม่ได้เก็บไว้ที่ใด
return $thisการ setters ของคุณ นอกจากนี้ยังช่วยให้คุณสามารถตั้งโซ่
คุณไม่สามารถทำสิ่งที่คุณขอได้ แต่คุณสามารถ "โกง" ได้โดยใช้ข้อเท็จจริงที่ว่าใน PHP คุณสามารถมีฟังก์ชันที่มีชื่อเดียวกับคลาสได้ ชื่อเหล่านั้นจะไม่ขัดแย้งกัน
ดังนั้นหากคุณประกาศคลาสเช่นนี้:
class Test {
public function __construct($param) {
$this->_var = $param;
}
public function myMethod() {
return $this->_var * 2;
}
protected $_var;
}
จากนั้นคุณสามารถประกาศฟังก์ชันที่ส่งคืนอินสแตนซ์ของคลาสนั้น - และมีชื่อเดียวกับคลาส:
function Test($param) {
return new Test($param);
}
และตอนนี้มันเป็นไปได้ที่จะใช้ซับเดียวอย่างที่คุณถามสิ่งเดียวคือคุณเรียกใช้ฟังก์ชันดังนั้นจึงไม่ใช้ใหม่:
$a = Test(10)->myMethod();
var_dump($a);
และได้ผล: ที่นี่ฉันได้รับ:
int 20
เป็นเอาต์พุต
และที่ดีกว่านั้นคุณสามารถใส่ phpdoc ในฟังก์ชันของคุณได้:
/**
* @return Test
*/
function Test($param) {
return new Test($param);
}
ด้วยวิธีนี้คุณจะมีคำใบ้ใน IDE ของคุณอย่างน้อยก็ด้วย Eclipse PDT 2.x; ดู screeshot:
แก้ไข 2010-11-30:เพียงเพื่อเป็นข้อมูลมีการส่ง RFC ใหม่เมื่อไม่กี่วันที่ผ่านมาซึ่งเสนอให้เพิ่มคุณสมบัตินี้ใน PHP เวอร์ชันอนาคต
ดู: ขอความคิดเห็น: อินสแตนซ์และวิธีการเรียก / การเข้าถึงคุณสมบัติ
ดังนั้นการทำสิ่งเหล่านี้อาจทำได้ใน PHP 5.4 หรือเวอร์ชันอื่นในอนาคต:
(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]
คุณสามารถทำได้ในระดับสากลมากขึ้นโดยกำหนดฟังก์ชันระบุตัวตน:
function identity($x) {
return $x;
}
identity(new Obj)->method();
ด้วยวิธีนี้คุณไม่จำเป็นต้องกำหนดฟังก์ชันสำหรับแต่ละคลาส
เกี่ยวกับ:
$obj = new Obj(); $method_result = $obj->method(); // ?
: P
ไม่นี่เป็นไปไม่ได้
คุณต้องกำหนดอินสแตนซ์ให้กับตัวแปรก่อนจึงจะเรียกใช้วิธีการใด ๆ ได้
หากคุณไม่ต้องการทำสิ่งนี้จริงๆคุณสามารถใช้โรงงานได้ตามที่ ropstah แนะนำ:
class ObjFactory{
public static function newObj(){
return new Obj();
}
}
ObjFactory::newObj()->method();
public static function public functionแนะนำให้ใช้แบบคงที่หรือไม่?
คุณสามารถใช้วิธีการโรงงานแบบคงที่เพื่อผลิตวัตถุ:
ObjectFactory::NewObj()->method();
ฉันเองก็กำลังมองหาหนึ่งซับเพื่อทำสิ่งนี้ให้สำเร็จโดยเป็นส่วนหนึ่งของนิพจน์เดียวสำหรับการแปลงวันที่จากรูปแบบหนึ่งไปเป็นอีกรูปแบบหนึ่ง ฉันชอบทำสิ่งนี้ในโค้ดบรรทัดเดียวเพราะมันเป็นการดำเนินการเชิงตรรกะเดียว ดังนั้นนี่จึงเป็นความลับเล็กน้อย แต่ให้คุณสร้างอินสแตนซ์และใช้วัตถุวันที่ภายในบรรทัดเดียว:
$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');
อีกวิธีหนึ่งในการแปลงสตริงวันที่จากรูปแบบหนึ่งไปยังอีกรูปแบบหนึ่งคือการใช้ฟังก์ชันตัวช่วยในการจัดการส่วน OO ของโค้ด:
function convertDate($oldDateString,$newDateFormatString) {
$d = new DateTime($oldDateString);
return $d->format($newDateFormatString);
}
$myNewDate = convertDate($myOldDate,'F d, Y');
ฉันคิดว่าแนวทางเชิงวัตถุนั้นยอดเยี่ยมและจำเป็น แต่บางครั้งก็อาจน่าเบื่อโดยต้องใช้ขั้นตอนมากเกินไปในการดำเนินการง่ายๆให้สำเร็จ
ฉันเห็นว่ามันค่อนข้างเก่าเมื่อมีคำถาม แต่นี่คือสิ่งที่ฉันคิดว่าควรกล่าวถึง:
เมธอดคลาสพิเศษที่เรียกว่า "__call ()" สามารถใช้เพื่อสร้างไอเท็มใหม่ภายในคลาส คุณใช้สิ่งนี้:
<?php
class test
{
function __call($func,$args)
{
echo "I am here - $func\n";
}
}
$a = new test();
$a->new( "My new class" );
?>
ผลลัพธ์ควรเป็น:
I am here - new
ดังนั้นคุณสามารถหลอก PHP ให้สร้างคำสั่ง "ใหม่" ภายในคลาสระดับบนสุดของคุณ (หรือคลาสใด ๆ ก็ได้) และใส่คำสั่ง include ของคุณในฟังก์ชัน __call () เพื่อรวมคลาสที่คุณขอ แน่นอนคุณอาจต้องการทดสอบ $ func เพื่อให้แน่ใจว่าเป็นคำสั่ง "ใหม่" ที่ส่งไปยังคำสั่ง __call () และ (แน่นอน) คุณอาจมีคำสั่งอื่น ๆ ด้วยเนื่องจากการทำงานของ __call ()
เพียงแค่เราทำได้
$method_result = (new Obj())->method();