如何使用PHP& amp;笨

时间:2010-09-26 21:07:10

标签: php mysql activerecord codeigniter

我正在试图弄清楚如何在我的第一个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或更多,它应该只说出其中两个的名字,IE“你,名字二,还有其他5个人已经读过这个。”

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

有更简单的方法吗?

非常感谢, 马库斯

4 个答案:

答案 0 :(得分:3)

我会说使用带范围的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;
  }

答案 1 :(得分: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'
}

这应该可以帮到你。这几乎是伪代码,但逻辑是实现你想要的(我相信)。如果你只是展示了一些用户,但是很容易就能完成,你显然想要不获取所有行。

答案 2 :(得分:1)

实际上有几个地方我们可以对此进行优化。

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));

答案 3 :(得分:0)

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

    // 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>';
    }