Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 带ORM的递归-逻辑错误_Php_Codeigniter_Doctrine - Fatal编程技术网

Php 带ORM的递归-逻辑错误

Php 带ORM的递归-逻辑错误,php,codeigniter,doctrine,Php,Codeigniter,Doctrine,你好 我用Codeigniter和条令建立了一种日常随机图像系统 有一个键函数,返回每日图像或设置新图像。我使用递归调用,但有时一天选择两个图像 我想这是个愚蠢的错误。。也许在$this->find_daily()之前调用类似于“Doctrine::doAllAndClear”的东西

你好

我用Codeigniter和条令建立了一种日常随机图像系统

有一个键函数,返回每日图像或设置新图像。我使用递归调用,但有时一天选择两个图像

我想这是个愚蠢的错误。。也许在
$this->find_daily()之前调用类似于“Doctrine::doAllAndClear”的东西
还是最好不要使用递归调用


谢谢。

嗯,我根本没有测试过这个,但我可能更愿意像这样编写代码;希望这能给你一些想法:

  function find_daily() {
    $connection = Doctrine_Manager::connection();
    $connection->setCharset('utf8');

    // Make sure "today" doesn't change while the script runs
    $today = date("Y-m-d"); 

    // Find an image with today's date.
    $q = Doctrine_Query::create()
      ->from('Image')
      ->where('daily_date = ?', $today)
      ->limit(1);

    $image = $q->fetchOne();

    if (!$image) {
      // There was no image with today's date, so pick one from the queue at random instead.
      $q = Doctrine_Query::create()
        ->from('Image')
        ->where('daily_date = ?', "0000-00-00")
        ->andWhere("dir =?","queue")
        ->orderBy("rand()")
        ->limit(1);

      $image = $q->fetchOne();
      // ToDo: Cope with there being no image in the queue

      $image->setDailyDate($today);
      $image->setDir("archive");
      $image->save();
    }
    return $image;
  }
但是,您需要考虑如果两个人同时点击您的脚本会发生什么。在这种情况下,他们可能都会获取当天的新图像(因为他们可以同时运行第一个
SELECT
,并且都会得到一个结果,表明还没有每日图像。)

为了避免这种情况,我想您应该将其包装在一个事务中,并设置一个事务隔离级别,以便函数的第一个调用方“赢得”竞争条件,随后的调用方将阻塞,直到安全保存更新为止。我不完全确定你会怎么做,但这并不难

检查手册,开始时是一个
beginTransaction()
,结束时是一个
commit()
,所有涉及
$tx=$conn->transaction的操作之前都要先进行设置$tx->setIsolation('SERIALIZABLE')(否则两个用户可能仍然可以同时运行SELECT)可能是您所需要的全部,但您可能希望等待真正了解该原则的人对此发表评论


我还在脚本开始时保存了“今天”的日期,否则,如果脚本在午夜运行,则在选择和以后的更新过程中可能会出现不同的日期。

请耐心等待,因为我可能会被您的代码弄糊涂,但为什么要递归?比如说,为什么不返回$i
而不是再次调用
$this->find_daily()
?同样,如果你递归,无论调用什么,你都不会收到返回值,是吗?因为您没有返回递归调用的结果。我们可能需要查看函数的其余部分来了解发生了什么。另外,这段代码是如何启动的?是否有可能两个用户同时运行此功能?@matt你说得对,我可以不使用递归就完成此操作。。。我很可能会这样做,但我会很高兴发现我做错了什么。此代码在某些用户查看每日图像时使用。我现在大约有10个用户(项目不是公开的)。我的表是可时间戳的,并且两个图像同时被选中(db行更新)。我认为现在不可能在同一个脚本上同时有两个用户(在午夜)(这个问题反复显示)。当他们相同时,时间戳是什么?你提到午夜是因为时间戳在午夜左右吗?如果这个脚本在午夜运行,
date(“Y-m-d”)
的值可能会在运行时发生变化,当然……在每次更新的每一行上自动放置实际的日期和时间,我指的是时间戳。我认为在脚本执行期间更改日期并没有问题,在最坏的情况下,系统会返回旧映像。这期“双选”杂志每两天都会显示一次。谢谢,交易对我来说是全新的。我修改了代码,以避免这种愚蠢的递归。@Jan想一想,我不完全相信事务可以在这里完成这项工作;您正在根据之前查看整个表的结果进行更新(以查找是否有包含今天日期的行)。在运行此函数时锁定表可以完成此任务,但在你接受答案之前,你可能想等着看是否有人有更好的想法。等待这正是我现在正在做的:)这是一个小项目,所以我能负担得起。谢谢。我终于找到了那个虫子的源头:)这是我的愚蠢,我在自助餐厅解决了它。我忘记了另一个图像(带有描述)是使用相同的函数生成的。
  function find_daily() {
    $connection = Doctrine_Manager::connection();
    $connection->setCharset('utf8');

    // Make sure "today" doesn't change while the script runs
    $today = date("Y-m-d"); 

    // Find an image with today's date.
    $q = Doctrine_Query::create()
      ->from('Image')
      ->where('daily_date = ?', $today)
      ->limit(1);

    $image = $q->fetchOne();

    if (!$image) {
      // There was no image with today's date, so pick one from the queue at random instead.
      $q = Doctrine_Query::create()
        ->from('Image')
        ->where('daily_date = ?', "0000-00-00")
        ->andWhere("dir =?","queue")
        ->orderBy("rand()")
        ->limit(1);

      $image = $q->fetchOne();
      // ToDo: Cope with there being no image in the queue

      $image->setDailyDate($today);
      $image->setDir("archive");
      $image->save();
    }
    return $image;
  }