【问题标题】:Implementing CakePHP find() operations in datasource在数据源中实现 CakePHP find() 操作
【发布时间】:2025-12-12 09:00:01
【问题描述】:

我正在我的 CakePHP 应用程序中实现一个自定义数据源,我已经实现了一个数据源的基本功能(read()listSources()describe())。 数据源使用 Xml 作为输入,我真的很想在 Xml 上使用 find('neighbors') 并且想知道 Cake 是否“自动”实现了这个功能(因为有 read() 函数),或者我是否需要扩展数据源不知何故。我还没有找到具体的例子,所以我希望 SO 社区能够提供帮助。

下面是当前的数据源实现。

<?php
App::import('Core', 'Xml');

class AppdataSource extends DataSource {
  protected $_schema = array(
  'apps' => array(
   'id' => array(
    'type' => 'integer',
    'null' => true,
    'key' => 'primary',
    'length' => 11,
   ),
   'type' => array(
    'type' => 'string',
    'null' => true,
    'length' => 140
   ),
   'title' => array(
    'type' => 'string',
    'null' => true,
    'length' => 255
   ),
   'subtitle' => array(
    'type' => 'string',
    'null' => true,
    'length' => 255
   ),
   'body' => array(
    'type' => 'text',
    'null' => true,
   ),
   'date' => array(
    'type' => 'date',
    'null' => true,
   ),
  )
 );

  public function listSources() {
  return array('apps');
 }

  public function describe($model) {
  return $this->_schema['apps'];
 }

  function calculate(&$model, $func, $params = array()) {
   return '__'.$func;
  }

  function __getPage($items = null, $queryData = array()) {
  if (empty($queryData['limit']) ) {
   return $items;
  }
  $limit = $queryData['limit'];
  $page = $queryData['page'];
  $offset = $limit * ($page-1);
  return array_slice($items, $offset, $limit);
 }

  function __sortItems(&$model, $items, $order) {
  if ( empty($order) || empty($order[0]) ) {
   return $items;
  }

  $sorting = array();
  foreach( $order as $orderItem ) {
   if ( is_string($orderItem) ) {
    $field = $orderItem;
    $direction = 'asc';
   }
   else {
    foreach( $orderItem as $field => $direction ) {
     continue;
    }
   }

   $field = str_replace($model->alias.'.', '', $field);

   $values =  Set::extract($items, '{n}.'.$field);
   if ( in_array($field, array('lastBuildDate', 'pubDate')) ) {
    foreach($values as $i => $value) {
     $values[$i] = strtotime($value);
    }
   }
   $sorting[] = $values;

   switch(low($direction)) {
    case 'asc':
     $direction = SORT_ASC;
     break;
    case 'desc':
     $direction = SORT_DESC;
     break;
    default:
     trigger_error('Invalid sorting direction '. low($direction));
   }
   $sorting[] = $direction;
  }

  $sorting[] = &$items;
  $sorting[] = $direction;
  call_user_func_array('array_multisort', $sorting);

  return $items;
 }

  public function read($model, $queryData = array()) {
    $feedPath = 'xml/example.xml';
    $xml = new Xml($feedPath);
    $xml = $xml->toArray();
  foreach ($xml['Items']['Item'] as $record) {
    $record = array('App' => $record);
    $results[] = $record;
  }
    $results = $this->__getPage($results, $queryData);
    //Return item count
    if (Set::extract($queryData, 'fields') == '__count' ) {
     return array(array($model->alias => array('count' => count($results))));
    }
    return $results;
 }
}
?>

基本 Xml 结构:

<items>
 <item id="1">
   <type>Type</type>
   <title>Title</title>
   <subtitle>Subtitle</subtitle>
   <date>15-12-2010</date>
   <body>Body text</body>
 </item>
</items>

编辑:

应该更仔细地阅读手册:

这几乎就是全部 它。通过将此数据源耦合到 模型,然后您就可以使用 模型::find()/save() 就像你一样 通常,以及适当的数据 和/或用于调用这些的参数 方法将传递给 数据源本身,你可以在哪里 决定实现任何功能 您需要(例如 Model::find options 比如'conditions'解析,'limit' 甚至您自己的自定义参数)。

【问题讨论】:

    标签: php xml cakephp datasource neighbours


    【解决方案1】:

    我怀疑你必须展示 Cake 如何通过在数据源中定义一个方法来查找邻居。

    【讨论】:

    • 可能不会。我假设如果 Cake 知道如何在该数据源上找到邻居,那么该数据源就已经被定义了。
    • 恐怕你是对的,我应该更仔细地阅读有关数据源的手册 (book.cakephp.org/view/848/Basic-API-For-DataSources)。我已经用相关信息更新了我原来的问题。