我正在试图弄清楚如何在我的第一个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()来查看登录用户是否已经读取并尝试报告,但我只是在处理逻辑时遇到了一些麻烦。
有更简单的方法吗?
非常感谢, 马库斯
答案 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>';
}