2012-12-31 13 views
11

CakePHP của trông giống như:

afterFind(array $results, boolean $primary = false) 

Theo tài liệu:

Tham số $primary chỉ ra hay không mô hình hiện tại là mô hình mà các truy vấn nguồn gốc hoặc có hay không mô hình này được truy vấn như một hiệp hội. Nếu mô hình được truy vấn dưới dạng liên kết, định dạng của $results có thể khác nhau.

Họ thể khác nhau, nhưng thử nghiệm cho thấy rằng họ không luôn khác nhau. Theo như tôi có thể nói, tham số $primary không thực sự hữu ích. Nếu nó được đặt thành false, bạn có thể hoặc không thể có cấu trúc dữ liệu phẳng, vì vậy bạn có thể hoặc không thể kết thúc với thông báo lỗi "không thể sử dụng chuỗi bù đắp dưới dạng mảng" đáng sợ.

Mặc dù tôi đã không thử nó chưa, suy nghĩ của tôi dựa trên các tài liệu sẽ lờ $primary cờ hoàn toàn và chỉ cần kiểm tra các dữ liệu:

public function afterFind($results, $primary = false) { 
    if (array_key_exists(0, $results) { 
    // operate on $results[0]['User']['fieldname'] 
    } else { 
    // operate on $results['fieldname'] 
    } 
    return $results; 
} 

Đây là hackish và tôi không thích nó, nhưng có vẻ hữu ích hơn $primary.

quy định rõ ràng, câu hỏi của tôi là:

  1. cờ $primary là gì thực sự hữu ích cho?
  2. Tôi có đúng là không hữu ích để xác định cấu trúc của mảng $results hay tôi đã bỏ lỡ điều gì đó ở đó?

Trả lời

11

Thật vậy tham số $primary dường như chỉ có ích trong việc cảnh báo cho bạn về những trường hợp nơi định dạng của $results là không thể đoán trước. Nó không hữu ích trong việc xác định định dạng của $results.

biết thêm thông tin ở đây: https://groups.google.com/forum/?fromgroups=#!topic/cake-php/Mqufi67UoFo

Các giải pháp đưa ra có để kiểm tra !isset($results[$this->primaryKey]) để xem những gì định dạng $results là. Đây cũng là một chút của một hack, nhưng cho là tốt hơn so với kiểm tra cho một phím '0'.

Các giải pháp tôi cuối cùng đã đưa ra là để làm một cái gì đó như thế này:

public function afterFind($results, $useless) { 

    // check for the primaryKey field 
    if(!isset($results[$this->primaryKey])) { 
     // standard format, use the array directly 
     $resultsArray =& $results; 
    } else { 
     // stupid format, create a dummy array 
     $resultsArray = array(array()); 
     // and push a reference to the single value into our array 
     $resultsArray[0][$this->alias] =& $results; 
    } 

    // iterate through $resultsArray 
    foreach($resultsArray as &$result) { 
     // operate on $result[$this->alias]['fieldname'] 
     // one piece of code for both cases. yay! 
    } 

    // return $results in whichever format it came in 
    // as but with the values modified by reference 
    return parent::afterFind($results, $useless); 
} 

Điều này làm giảm sự trùng lặp mã bởi vì bạn không cần phải viết logic lĩnh vực thay đổi của bạn hai lần (một lần cho một mảng và một lần cho không phải mảng).

Bạn có thể tránh toàn bộ nội dung tham chiếu bằng cách chỉ trả lại $resultsArray ở cuối phương thức, nhưng tôi không chắc chắn vấn đề nào có thể gây ra nếu CakePHP (hoặc một số lớp cha mẹ khác) mong đợi $results nó đã được thông qua. Cộng với cách này không có chi phí sao chép mảng $results.

+1

Đã khắc phục sự cố này ngay hôm nay. Đôi khi tập hợp kết quả $ là một mảng đa chiều, đôi khi không phải. Tôi cảm thấy như đây là một vấn đề khá lớn. – vinhboy

+0

Tôi có thể hôn bạn. Điều này vừa cứu tôi sau khi đập đầu tôi trong 4 giờ. – bowlerae

-2

câu trả lời trong cuốn sách ...

Tham số chính $ chỉ ra hay không mô hình hiện tại là mô hình mà các truy vấn nguồn gốc hoặc có hay không mô hình này được truy vấn như một liên kết. Nếu mô hình được truy vấn dưới dạng liên kết định dạng của $ kết quả có thể khác nhau;

Mã mong $ chính là đúng sẽ có thể nhận được "Không thể sử dụng chuỗi bù đắp dưới dạng mảng" lỗi nghiêm trọng từ PHP nếu tìm thấy đệ quy là được sử dụng.

Do đó nó có thể hữu ích trong các tình huống nhất định cho việc xử lý logic và có thể có thể được sử dụng để có một tiếng gõ vào hiệu lực vào $ kết quả của bạn

+4

Bạn có thể nhận thấy tôi đã trích dẫn cùng một phần tài liệu. Tuy nhiên, như tôi đã nói trong câu hỏi của tôi, nếu '$ primary' được đặt thành' false' không nhất thiết có nghĩa là '$ results' sẽ được định dạng khác. Như các tài liệu nói, "định dạng của' $ kết quả' ** có thể ** khác nhau. " Nhưng sau đó một lần nữa, nó có thể không. Thử nghiệm hỗ trợ điều này. – eaj

0

Tôi đã gặp sự cố này. Câu trả lời được chấp nhận hoạt động tốt. Tuy nhiên, tôi phải thực hiện một điều chỉnh nhỏ. Nếu bạn đang tìm cách sửa đổi một trường ví dụ: xây dựng tên tệp hoàn chỉnh đủ điều kiện từ biểu trưng, ​​tốt hơn là tạo trường mới, dưới dạng "return parent :: afterFind ($ results, $ useless);" sẽ làm điều đó hai lần nếu mô hình tìm thấy được gọi từ một số mô hình khác.

foreach($resultsArray as &$result) { 
     // operate on $result[$this->alias]['fieldname'] 
     // one piece of code for both cases. yay! 

     // Added logoFull instead of modifying logo 
     if(isset($result[$this->alias]['logo'])){ 
      $result[$this->alias]['logoFull'] = Configure::read('urlImg') . 'logos' . DIRECTORY_SEPARATOR . 
       'carrier' . DIRECTORY_SEPARATOR . $result[$this->alias]['logo']; 
     } 
    } 
1

Nếu bạn có thể không phải lúc nào phụ thuộc vào primaryKey là trong danh sách các lĩnh vực và bạn biết chìa khóa bạn đang tìm kiếm, bạn có thể nhận được ngay với một cái gì đó một chút đơn giản hơn. Dưới đây là ví dụ:

/** 
* Decrypt password 
* 
* @see Model::afterFind() 
*/ 
public function afterFind($results, $primary = false) {   
    if (!empty($results['password'])) { 
     $results['password'] = Security::rijndael($results['password'], Configure::read('encrypt.key'), 'decrypt'); 
     return $results; 
    } 

    foreach ($results as &$r) { 
     if (!empty($r[$this->alias]['password'])) { 
      $r[$this->alias]['password'] = Security::rijndael($r[$this->alias]['password'], Configure::read('encrypt.key'), 'decrypt'); 
     } 
    } 
    return $results; 
}