【问题标题】:CakePHP 3: Error while passing an array in URLCakePHP 3:在 URL 中传递数组时出错
【发布时间】:2016-11-03 21:17:15
【问题描述】:

我正在尝试将datetime 变量传递到我的exportcsv 方法中,以生成带有指定时间段数据的.csv 文件。

两个变量都是如下所示的关联数组:

[
 'beginning' => [
    'year' => '2016',
    'month' => '06',
    'day' => '23',
    'hour' => '11',
    'minute' => '15'
  ],
  'end' => [
    'year' => '2016',
    'month' => '06',
    'day' => '29',
    'hour' => '11',
    'minute' => '15'
   ]
]

当我尝试传递变量时,我收到一条错误消息(是的,我收到了相同的两个警告):

Warning (2): rawurlencode() expects parameter 1 to be string, array given [CORE\src\Routing\Route\Route.php, line 574]

Warning (2): rawurlencode() expects parameter 1 to be string, array given [CORE\src\Routing\Route\Route.php, line 574]

rawurlencode()是一个基本的PHP函数,这是line 574

$pass = implode('/', array_map('rawurlencode', $pass));

URL 重写似乎有些问题,但坦率地说,我不知道如何解决它。有什么想法吗?

EventsController中的exportcsv方法

public function exportcsv($beginning = null, $end = null)
{
 if ($this->request->is('post')) {
  $beginning = $this->request->data['Export']['beginning']; 
  $end = $this->request->data['Export']['end'];              

  return $this->redirect([$beginning, $end]);
 }

 if (!$beginning && !$end) {
  return $this->render();
 }

 $this->response->download('export.csv');
$data = $this->Events->find('all')
                          ->select([
                            'title',
                            'created',
                            'description',
                            'ended',
                            'working_hours',
                            'price',
                            'username' => 'Users.name',
                            'statusname' => 'Statuses.name',
                            'employeename' => 'Employees.name'
                          ])
                          ->leftJoinWith('Statuses')
                          ->leftJoinWith('Users')
                          ->leftJoinWith('Employees')
                          ->where(["created BETWEEN " . $beginning . " AND " . $end])
                          ->autoFields(true)
                          ->toArray();
$_serialize = 'data';
$_delimiter = chr(9); //tab
$_extract = ['title', 'created', 'description', 'ended', 'working_hours', 'price', 'username', 'statusname', 'employeename'];
$this->set(compact('data', '_serialize','_delimiter', '_extract'));
$this->viewBuilder()->className('CsvView.Csv');
return;
}

exportcsv.ctp查看:

<div class="events form large-6 medium-4 columns content">
  <?= $this->Form->create('Export'); ?>
  <?= $this->Form->input('beginning', array('type'=>'datetime', 'interval' => 15, 'label' => 'Beginning:')); ?>
  <?= $this->Form->input('end', array('type'=>'datetime',  'interval' => 15, 'label' => 'End:')); ?>
  <?= $this->Form->button(__('Add')) ?>
  <?= $this->Form->end() ?>
</div>

【问题讨论】:

  • rawurlencode()line 574 在哪里?
  • 看起来rawurlencode()是一个基本的PHP函数。这是上述行:$pass = implode('/', array_map('rawurlencode', $pass));
  • 为什么不在代码中包含这一行?使用此代码更新您的问题
  • 所以你已经注意到你不能传递数组......尝试传递字符串怎么样,即从你的单独值构建正确的日期时间字符串!?旁注:您的where() 条件容易发生 SQL 注入!您最好使用表达式或适当的手动绑定! stackoverflow.com/questions/26430259/…
  • @ndm 非常感谢您的回复。我希望有另一种方法来解决这个问题,但这也有效。另外,感谢您提醒我安全问题,这非常重要。请将此评论添加为答案,我会接受。

标签: php cakephp url-rewriting cakephp-3.0


【解决方案1】:

您不能在 URL 数组中传递数组,路由器不支持。此外,您还需要通过相反,将您的单个值转换为正确的日期时间字符串,您可以通过 DateTimeType 类轻松地做到这一点,类似于

if ($this->request->is('post')) {
    $beginning = $this->request->data('Export.beginning');
    $end = $this->request->data('Export.end');

    $type = \Cake\Database\Type::build('datetime');
    $beginning = $type->marshal($beginning)->format('Y-m-d H:i:s');
    $end = $type->marshal($end)->format('Y-m-d H:i:s');

    return $this->redirect([
        $beginning,
        $end
    ]);
}

此外,正如 cmets 中已经提到的,您需要修复您的 where() 调用,因为目前它存在 SQL 注入漏洞。 key =&gt; value 项的键,以及只有值的项,不会被绑定,而是直接插入到查询中!

Cakes 表达式构建器附带安全生成 BETWEEN 表达式的方法:

->where(function(\Cake\Database\Expression\QueryExpression $exp) use ($beginning, $end) {
    return $exp->between('Events.created', $beginning, $end);
});

另见

【讨论】:

    【解决方案2】:

    您的重定向错误

    return $this->redirect([
        'controller' => 'yourController', 
        'action' => 'yourAction', 
        $yourData]
    );
    

    有关此主题的更多信息,请参阅Cookbook

    【讨论】:

    • 感谢您的回复。我试图将我的重定向更改为这样的东西:return $this-&gt;redirect(['controller' =&gt; 'Events', 'action' =&gt; 'exportcsv', $beginning, $end]); 但它给出了同样的错误,当我尝试这个时:return $this-&gt;redirect(['controller' =&gt; 'Events', 'action' =&gt; 'exportcsv', [$beginning, $end]]); 没有任何反应。它没有开始下载文件,只是重新加载页面,所以我假设值没有分配给 $beginning$end
    猜你喜欢
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多