Php 如何从Limition中记录集的所有实体中删除特定字段?
我正在使用MySQL作为我所有型号的数据库连接适配器。我有一个下载模型和控制器,带有一个索引函数,根据请求传递的类型呈现Php 如何从Limition中记录集的所有实体中删除特定字段?,php,recordset,lithium,Php,Recordset,Lithium,我正在使用MySQL作为我所有型号的数据库连接适配器。我有一个下载模型和控制器,带有一个索引函数,根据请求传递的类型呈现HTML表或CSV文件。我还有一个CSVmedia类型来处理数据数组,该数组按预期工作(将数组键作为标题输出,然后为每行数据输出数组值) 我希望执行相同的查找查询,但如果要呈现CSV文件,则从记录集中删除ID字段。您会注意到下载ID正在被提取,即使它不在fields数组中,因此根据请求类型简单地更改fields数组将不起作用 我在下载控制器的索引操作中尝试了以下操作: <
HTML
表或CSV
文件。我还有一个CSV
media类型来处理数据数组,该数组按预期工作(将数组键作为标题输出,然后为每行数据输出数组值)
我希望执行相同的查找查询,但如果要呈现CSV
文件,则从记录集中删除ID
字段。您会注意到下载ID正在被提取,即使它不在fields数组中,因此根据请求类型简单地更改fields数组将不起作用
我在下载控制器的索引操作中尝试了以下操作:
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
if ($this->request->params['type'] == 'csv') {
$downloads->each(function ($download) {
// THIS DOES NOT WORK
unset($download->id, $download->user_id);
// I HAVE TRIED THIS HERE AND THE ID FIELDS STILL EXIST
// var_dump($download->data());
// exit;
return $download;
});
return $this->render(array('csv' => $downloads->to('array')));
}
return compact('downloads');
}
}
?>
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
$this->request->privateKeys = array('id', 'user_id');
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
return compact('downloads');
}
}
?>
我认为在实体对象上有一个\u unset()
魔术方法,当您调用实体字段上的标准PHP
unset()
函数时,会调用该方法
如果有一个$recordSet->removeField('field')
函数就好了,但我找不到
任何帮助都将不胜感激。也许你应该做
$downloads=$downloads->to('array')
,使用for循环迭代该数组,从每行中删除这些字段,然后返回该数组。如果您必须为许多操作执行相同的操作,您可以设置一个自定义媒体处理程序,该处理程序可以更改数据,而不需要控制器中的逻辑
看看锂媒体类单元测试
通过使用自定义处理程序,还可以避免在控制器中有太多的逻辑。此示例还自动从数据中的键生成标题行
在config/bootstrap/media.php
中:
Media::type('csv', 'application/csv', array(
'encode' => function($data, $handler, $response) {
$request = $handler['request'];
$privateKeys = null;
if ($request->privateKeys) {
$privateKeys = array_fill_keys($request->privateKeys, true);
}
// assuming your csv data is the first key in
// the template data and the first row keys names
// can be used as headers
$data = current($data);
$row = (array) current($data);
if ($privateKeys) {
$row = array_diff_key($row, $privateKeys);
}
$headers = array_keys($row);
ob_start();
$out = fopen('php://output', 'w');
fputcsv($out, $headers);
foreach ($data as $record) {
if (!is_array($record)) {
$record = (array) $record;
}
if ($privateKeys) {
$record = array_diff_key($record, $privateKeys);
}
fputcsv($out, $record);
}
fclose($out);
return ob_get_clean();
}
));
您的控制器:
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
if ($this->request->params['type'] == 'csv') {
$downloads->each(function ($download) {
// THIS DOES NOT WORK
unset($download->id, $download->user_id);
// I HAVE TRIED THIS HERE AND THE ID FIELDS STILL EXIST
// var_dump($download->data());
// exit;
return $download;
});
return $this->render(array('csv' => $downloads->to('array')));
}
return compact('downloads');
}
}
?>
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
$this->request->privateKeys = array('id', 'user_id');
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
return compact('downloads');
}
}
?>
为什么不动态设置
$fields
数组
public function index() {
$type = $this->request->params['type'];
//Exclude `user_id` if request type is CSV
$fields = $type == 'csv' ? array('Surveys.name') : array('user_id', 'Surveys.name');
$conditions = array(...);
$with = array('Surveys');
$order = array('created' => 'desc');
$downloads = Downloads::find('all', compact('conditions', 'fields', 'with', 'order'));
//Return different render type if CSV
return $type == 'csv' ? $this->render(array('csv' => $downloads->data())) : compact('downloads');
}
在本例中,您可以看到我是如何为您的CSV处理程序发送数组的,否则将是
$downloads
记录集对象进入视图。我重新阅读了您的问题,显然您已经知道自定义媒体处理程序。但无论如何,我希望这能给你一些想法。谢谢你,我很快会尝试一下,让你知道它是如何进行的,但它看起来确实像一个更干净的解决方案。谢谢你!只有一件事,通过使用lithium\util\Set::flatte()
“将多维数组折叠为单个维度,为每个数组元素的键使用分隔的数组路径,即array(array('Foo'=>array('Bar'=>Far'))
变成array('0.Foo.Bar'=>Far')
”@韭菜我把代码放在Github上-。您打算在哪里使用“展平”?在$data
上?如果你制作了一个已编辑版本的链接,则发布一个链接。这仍然会获取下载ID,目的是删除所有ID字段,而不仅仅是用户ID字段。