Làm thế nào để sao chép bộ sưu tập trong Magento?


12

Tôi có một bộ sưu tập trong một phương thức mà tôi muốn thực hiện hai thao tác khác nhau trên bộ sưu tập này. Vì vậy, tôi muốn hai bản sao riêng biệt của cùng một bộ sưu tập, sau đó gán một trong hai bộ sưu tập cho bộ sưu tập gốc và trả lại.

Để làm cho nó đơn giản, giả sử tôi có một bộ sưu tập đối tượng được gọi $collection.

Bây giờ, tôi đang thử nó với nhân bản PHP vì tôi không biết liệu có bộ sưu tập Magento nào được nhân bản hay không.

$coll1 = clone $collection;
$coll2 = clone $collection;

Bây giờ tôi đang cố gắng thực hiện các hoạt động khác nhau trên hai bản sao riêng biệt này của bộ sưu tập gốc, đại loại như thế.

$coll1->getSelect()->where('some where condition');
$coll2->getSelect()->where('some different where condition');
if($coll1->count() == 0) {
    $collection = $coll2;
} else {
    $collection = $coll1;
}

Nhưng điều kỳ lạ là, cả hai bộ sưu tập nhân bản này đều có cả những điều kiện được giao! Điều kiện $ coll1 được áp dụng cho $ coll2 cùng với điều kiện của $ coll2 và ngược lại.

Có ai biết làm thế nào để đạt được điều này?

Cảm ơn!

Câu trả lời:


14

Việc sử dụng toán tử nhân bản PHP, trong đó muốn nhân bản sâu, yêu cầu các lớp lưu trữ các đối tượng trên các thuộc tính thực hiện phương thức __clone để sao chép các đối tượng. Nếu họ không định nghĩa nó, các thuộc tính trên cả hai trường hợp sẽ tham chiếu cùng một đối tượng.

Magento không triển khai __clone trên bản tóm tắt bộ sưu tập của nó và do đó không hỗ trợ nhân bản sâu như bạn muốn.

Đề nghị của tôi là tìm kiếm những cách khác để thực hiện những gì bạn muốn làm, vì nhân bản một bộ sưu tập có thể khá tốn kém.

Ví dụ bạn đã đưa ra (ví dụ) có thể được thay đổi để sao chép lựa chọn, sửa đổi nó để chọn một số lượng các bản ghi mà nó sẽ được tải và sau đó dựa trên kết quả đó sửa đổi bộ sưu tập. Điều này cũng sẽ hoạt động tốt hơn vì bạn sẽ không tải một bộ sưu tập và đếm nó chỉ để xác định cái nào sẽ sử dụng.

EDIT: Dưới đây trình bày cách lấy số lượng mà không tải hoặc thực sự sửa đổi bộ sưu tập.

$collection = Mage::getModel(...)->getCollection();

$count = $collection->getSelectCountSql();
$count->where('some where condition');
if ($count->query()->fetchColumn() == 0) {
    ...
} else {
    ...
}

Chỉ cần một chi tiết nhỏ: Thông tin về nơi được lưu trong $collection->getSelect()và không nằm trong chính bộ sưu tập.
Fabian Blechschmidt

Cảm ơn về câu trả lời. Nhưng sau khi áp dụng điều kiện chỉ có tôi muốn biết số lượng bộ sưu tập, và dựa vào số đó, tôi chỉ muốn quyết định có sử dụng điều kiện khác nhau hay không. Bạn có thể đăng một số đoạn mã để hiểu rõ hơn về cách thực hiện không?
MagExt

Cập nhật câu trả lời với một ví dụ mã. Như @FabianBlechschmidt đã chỉ ra, vị trí được chọn, đó là nơi mà sự cố cụ thể của bạn xuất phát do nó không được nhân bản khi đối tượng bộ sưu tập được sao chép và cả hai đều đề cập đến cùng một đối tượng chọn.
davidalger

Cảm ơn đã cập nhật. Tôi chưa thử điều này vì tôi đã có giải pháp tương tự như thế.
MagExt

Trên thực tế nếu có một vấn đề nhân bản bộ sưu tập, tuần tự hóa và không xác định có thể hữu ích trong quá trình. Ngoài ra còn có các lựa chọn thay thế khác để sao chép trong PHP là khá tốt. Nhưng tất cả trong tất cả David đều đúng ... về cơ bản khi bạn nhân bản đối tượng bạn đang nhân bản con trỏ sang các Đối tượng lồng nhau cũng được gắn vào nó, mặc dù câu trả lời của anh ta không nói rõ vấn đề tiềm ẩn.
mprototype

1

Để mở rộng câu trả lời của @ davidalger, bạn có thể đặt lại lựa chọn nếu bạn muốn thực hiện một thao tác khác với số đếm - như vậy:

$select= $collection->getSelectCountSql()->reset();

$select
    ->from('newsletter_subscriber', array('some_column'))
    ->distinct();

Mặc dù vậy, hãy cẩn thận, điều này có thể có tác động bất lợi sau này trong quá trình vì điều này sửa đổi bộ sưu tập.

Cách tốt hơn là sao chép lựa chọn bằng cách nào đó, nhưng một bản sao nông sẽ không cắt nó vì đối tượng chứa các loại phức tạp (Varien_Db_Select cũng như Zend_Db_Select có một __clonephương thức).

Một cách để khắc phục điều này là lưu dữ liệu đã chọn, sửa đổi nó, chạy truy vấn của bạn, sau đó đặt lại dữ liệu chọn ban đầu.

Xem ở đây để biết ví dụ: https://ka.lpe.sh/2013/05/23/magento-clone-collection-how-to-clone-collection-in-magento/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.