【问题标题】:How to write this statement using PHP & CodeIgniter如何使用 PHP 和 CodeIgniter 编写此语句
【发布时间】:2010-09-26 21:07:10
【问题描述】:

我正试图弄清楚如何在我的第一个 CI 应用程序(也是唯一的第二个 PHP 应用程序)中编写语句,但我被卡住了。

我有一个联结表,其中包含各自表中的 book_id 和 user_id。我想找出谁读过一本书并将其回显,但我需要格式化才有意义。这是查询:

$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));

这是我对一个人的逻辑

// Get my user info
$user = $this->ion_auth->get_user();
// Tell me who has read it.
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
// If only one person has read it
if ($readQuery->num_rows() == 1) {
    $readResult = $readQuery->row();
    // And if that person was me...
    if ($readResult->user_id == $user->id) {
        $message = 'You have read this.';
    // If it was someone else...
    } else {
        $reader = $this->ion_auth->get_user($readResult->user_id);
        $message = "$reader->first_name $reader->last_name has read this";
    }
// If two people have read it
}

所以如果只有一个人读过它我就很好。但是当两个人读过它时,我想让它说“名字一和名字二读过这个”。如果登录的人没有阅读它。如果他们是两个人之一,它应该说“你和名字二已经读过这个”。

3-5 以此类推。如果有 3-5 个人读过,选项将是“名字一、名字二、名字三读过这个”或“你、名字二、名字三读过这个”。最多五个人

如果是 6 个或更多,它应该只说他们两个的名字,即“你,名字两个,还有 5 个其他人已经读过这个。”

我考虑为每个实例做一个条件,然后将所有用户推送到一个数组。然后我可以使用 in_array() 查看登录用户是否已阅读并尝试报告,但我只是在处理逻辑时遇到了一些麻烦。

有没有更简单的方法?

在此先感谢您, 马库斯

【问题讨论】:

    标签: php mysql activerecord codeigniter


    【解决方案1】:

    我会说使用带有范围的 switch 语句。您必须做一些杂技来处理是否包含“您”的问题。下面的代码未经测试,但可以为您提供大致的思路。

    $message = "";
    $readers = array();
    $me_included = 0; // Counter increment if you're included in the reader list
    
    $this->db->select('user_id');
    $readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));      
    foreach ($readQuery->result() as $row) {
      if ($row->user_id == $user->id) {
        $message = "You";
        $me_included = 1;
      } else {
        $readers[] = $this->ion_auth->get_user($row->user_id);
      }
    }
    
    $reader_count = $sizeof($readers) + $me_included;
    switch(TRUE) 
    {
      // One reader, not you
      case( ($reader_count == 1) && ($me_included == 0) ):
        $message .= $readers[0]->first_name . " " . $readers[0]->last_name . " has read this.";
        break;
      // Only you
      case( ($reader_count == 1) && ($me_included == 1) ):
        $message .= " have read this.";
        break;
      // Two readers
      case( ($reader_count == 2) ):
        for ($i = 0; $i <= sizeof($readers); $i++) {
          if ($i == sizeof($readers)) {
            $message .= " and ";
          }
          $message .= $readers[i]->first_name . " " . $readers[i]->last_name;
        }
        $message .= " have read this.";
        break;
      case( ($reader_count > 3) && ($reader_count < 6) ):
        if ($me_included) {
          $message .= ", ";
        }
        for ($i = 0; $i <= sizeof($readers); $i++) {
          if ($i == sizeof($readers)) {
            $message .= " and ";
          }
          $message .= $readers[i]->first_name . " " . $readers[i]->last_name;
          if ($i != sizeof($readers)) {
            $message .= ", ";
          } else {
            $message .= " have read this.";
          }
        }
        break;
      case( ($reader_count > 6) ):
        if ($me_included) {
          $message .= ", " . $readers[0]->first_name . " " . $readers[0]->last_name . " and " . ($reader_count - 2) . " others have read this.";
        } else {
        for ($i = 0; $i <= 1; $i++) {
          $message .= $readers[0]->first_name . " " . $readers[0]->last_name . ", " . $readers[1]->first_name . " " . $readers[1]->last_name . " and " . ($reader_count - 2) . " others have read this.";
        }
        break;
      }
    

    【讨论】:

    • 稍微修改一下就可以成功实现了。遗憾的是,我没有足够的空间在这里发布整个代码,但是一旦修改它就可以工作。感谢您的帮助。
    • 我讨厌看到无用的逻辑表达式 :) 在工作中我总是要处理 if(something) {} else { Do some work}... 或 if(true)... 让我很生气
    【解决方案2】:
    $users = array();
    while($row)
    {
      if(currentuser)
      {
        array_unshift($users,'You')
      }
      else
      {
        $users[] = row[name]
      }
    }
    
    $count = $max = count($users);
    if($max >= 6)
    {
      $max = 2;
    }
    
    $str = '';
    for($i=0;$i<$max;$i++)
    {
      $str .= ($str == '' ? '' : ($i == $count-1 && $count < 6 ? ' And ' : ', ') ) . $users[$i];
    }
    
    if($count >= 6)
    {
      $str .= ' and '.$count-2.' others'
    }
    

    这应该可以帮助您。它几乎是伪代码,但逻辑可以实现您想要的(我相信)。如果您只是显示一些用户,那么您显然不想获取所有行,但这很容易实现。

    【讨论】:

    • 我更喜欢这种设置 - 它看起来更干净 - 但我无法为我的场景实施它。我的大部分困惑来自这一行: $str .= ($str == '' ? '' : ($i == $count-1 && $count
    • 三元语句仅用于连接 - 所以如果 str 为空白,则不要附加任何内容,否则附加结果(如果我们是 str 的末尾并且我们少于 6,则 append 否则附加逗号)。我总是在用逗号分隔事物时使用它,这样你就不会在开头或结尾有多余的逗号
    • 不错。在您的解释之后,我能够实现这一点,并且它缩短了 40 行(30 行对 70 行)并且更易于维护。再次感谢。
    【解决方案3】:

    实际上有几个地方我们可以优化它。

    1) 在初始查询中,与 user 表进行 JOIN,这样我们就不必为每个名称再次查询多次:

    $readers = $this->db->select('id', 'first_name', 'last_name')->from('books_users')->join('users', 'books_users.id =users.id', 'left')->where('book_id' => $isbn);
    

    2) 此外,我们可以通过执行单独的查询来避免迭代整个(可能很大的)结果集以查看您是否阅读了它:

    $you_read = $this->db->get_where('books_users', array('book_id' => $isbn, 'user_id' => $user->id));
    

    【讨论】:

      【解决方案4】:

      为了完整起见,这是我使用的最终代码。希望它对某人有用。

          // Find out who has read this book
          // Get the users
          $current_user = $this->ion_auth->get_user();
          $users = $this->ion_auth->get_users();
          // Get the readers
          $this->db->select('user_id');
          $query = $this->db->get_where('books_users', array('book_id' => $isbn));
          // If there were results
          $readers = array();
          if ($query->num_rows() > 0) {
              foreach ($users as $user) {
                  if ($current_user->id == $user->id) {
                      array_unshift($readers, 'You');
                  } else {
                      $readers[] = $user->first_name . ' ' . $user->last_name;
                  }
                  $count = $max = count($readers);
                  if ($max >= 6) {
                      $max = 2;
                  }
                  $message = '';
                  for ($i = 0; $i < $max; $i++) {
                      $message .= ($message == '' ? '' : ($i == ($count - 1) && ($count < 6) ? ' and ' : ', ')) . $readers[$i];
                  }
                  if ($count >= 6) {
                      $message .= ' and ' . ($count - 2) . ' others';
                  }
                  $message .= ($count == 1 && !$current_user->id ? ' has ' : ' have ') . 'read this.';
              }
          } else {
              $message = '<a href="' . base_url() . 'books/' . $bookResult->filename . '">Be the first to read this.</a>';
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-17
        • 2017-01-12
        相关资源
        最近更新 更多