2011-10-02 41 views
5

Tôi hiện đang học tập để sử dụng Propel ORM, và tôi muốn sử dụng lại với tiêu chí cho hai truy vấn hơi khác nhau:Tại sao chúng ta phải gán một bản sao cho một biến mới?

$criteria = ArticleQuery::create() 
     ->filterByIsPublished(true) 
     ->orderByPublishFrom(Criteria::DESC) 
     ->joinWith('Article.Author') 
     ->keepQuery(); 

$this->news = $criteria 
     ->filterByType('news') 
     ->find(); 
$this->articles = $critera 
     ->filterByType('article') 
     ->find(); 

Tuy nhiên, điều này sẽ không hoạt động như mong đợi, bởi vì bây giờ các truy vấn cho bài viết sẽ cố gắng để tìm các mục có cả 'tin tức' và 'bài viết', tất nhiên là không thể.

Vì vậy, chúng ta cần phải nhận được một bản sao của đối tượng này, và những gì có vẻ trực quan đối với tôi là chỉ cần thêm từ khóa bản sao bên trong ngoặc đơn:

$this->news = (clone $criteria) 
     ->filterByType('news') 
     ->find(); 

Parse error: syntax error, unexpected T_OBJECT_OPERATOR

Thay vào đó chúng ta phải gán nó vào một biến trước khi chúng ta có thể sử dụng nó:

$clonedCritera = clone $criteria; 
$this->news = $clonedCriteria 
     ->filterByType('news') 
     ->find(); 

Bạn có hành vi tương tự với toán tử new. Tôi thấy các nhà phát triển propel đã phá vỡ giới hạn này bằng cách thay thế:
new ArticleQuery()->doOperations() với ArticleQuery::create()->doOperations().

Tại sao các nhà thiết kế ngôn ngữ PHP chọn làm theo cách này? Nếu bạn có thể sử dụng kết quả của các biểu thức này trực tiếp, nó sẽ làm cho mã thông thạo hơn và, trong một số trường hợp, dễ đọc hơn.

+0

Hrm. Tôi tự hỏi câu trả lời nào của tôi sẽ không phù hợp nhất ... –

+0

tại sao? thực sự là một câu hỏi thực sự tốt. "bởi vì php không phải là java" là câu trả lời tôi nhận được, khi tôi hỏi trong một số diễn đàn về một vấn đề phân tích cú pháp tương tự với "mới". theo quan điểm của tôi, trình phân tích cú pháp php có nhiều sai sót như vậy - chúng tôi chỉ có thể hy vọng rằng chúng sẽ được khắc phục vào một ngày nào đó trong tương lai ... – aurora

+0

@harald Tôi đã xem trang RFC này trong khi nghiên cứu vấn đề này. dưới sự thảo luận giữa các nhà phát triển PHP. https://wiki.php.net/rfc/instance-method-call – CheeseSucker

Trả lời

4

Tại sao chúng ta phải gán bản sao cho biến mới?

Thật không may, câu trả lời là các nhà phát triển đã không nhận được xung quanh để hỗ trợ dereferencing trực tiếp trên các đối tượng được trả về thông qua bản sao được nêu ra.

Trong PHP 4, bạn không thể "dereference" bất kỳ đối tượng nào được trả về theo phương thức. Bạn phải gán nó cho biến giả trước.

Trong phiên bản tiếp theo của PHP, array dereferencing sẽ được hỗ trợ.

Vì vậy, rõ ràng là nhóm dev gia tăng thêm các tính năng như vậy vào thời gian biểu của họ.

Điều tốt nhất tôi có thể cho bạn biết là request this functionality từ nhóm nhà phát triển.

+1

Yêu cầu được gửi: https://bugs.php.net/bug.php?id=55833 – CheeseSucker

Các vấn đề liên quan