#php #json #printing
#php #json #печать
Вопрос:
Я не уверен, почему, но когда я запускаю следующий код и в базе данных ничего нет, я получаю ошибку [false] при просмотре страницы PHP вместо правильного сообщения об ошибке
public function fetchfriends($userid)
{
$this->userid = $userid;
$contact_check = mysql_query("
SELECT *
FROM user_contact
WHERE from_userid = '{$this->userid}'
AND approved != 1
");
if(!mysql_num_rows($contact_check))
{
$arr = array("error" => "No Friends?<br/>Search above for New users or invite some friends.");
print json_encode($arr);
}
else
{
$friendlook = mysql_query("
SELECT friend.to_userid,
info.username,
info.firstname,
info.lastname,
info.status,
astatus.onlinestatus
FROM user_contact AS friend
LEFT JOIN user_info AS info ON friend.to_userid = info.id
LEFT JOIN user_online AS astatus ON friend.to_userid = astatus.userid
WHERE friend.from_userid = '{$this->userid}'
AND friend.approved = 1
AND friend.to_userid = info.id
ORDER BY astatus.onlinestatus DESC
");
$row = mysql_fetch_assoc($friendlook);
$rows[] = $row;
print json_encode($rows);
}
}
Мне было интересно, знает ли кто-нибудь, почему?
Комментарии:
1. Тебе действительно следует исправить отступ там, приятель. 🙂 Это действительно важно.
2. кажется, что вы пытаетесь получить значения нижнего запроса при условии, применяемом к верхнему запросу.
Ответ №1:
http://php.net/manual/en/function.mysql-fetch-assoc.php
Возвращаемые значения: Возвращает ассоциативный массив строк, соответствующий выбранной строке, или FALSE, если строк больше нет.»
Ваш оператор select возвращает 0
строки, mysql_fetch_assoc
возвращает false
, вы вставляете это значение false в $rows
, таким образом, вы получаете массив, содержащий одно значение false.
Используйте if($row === false)
или if($row)
, чтобы определить, получили ли вы правильную строку.
Ответ №2:
У вас есть 2 SQL-запроса, и вы только проверяете, есть ли у первого какие-либо результаты. Проблема в том, что если у первого есть результаты, а у второго нет, вы не получите сообщение об ошибке, но [false]
вы получаете сейчас.
Ваш код должен выглядеть примерно так:
public function fetchfriends($userid)
{
$this->userid = $userid;
$contact_check = mysql_query("SELECT * FROM user_contact WHERE from_userid = '{$this->userid}' AND approved != 1");
if(mysql_num_rows($contact_check))
{
$friendlook = mysql_query("SELECT friend.to_userid, info.username, info.firstname, info.lastname, info.status, astatus.onlinestatus FROM user_contact as friend LEFT JOIN user_info as info ON friend.to_userid = info.id LEFT JOIN user_online as astatus ON friend.to_userid = astatus.userid WHERE friend.to_userid = info.id AND friend.from_userid = '{$this->userid}' AND friend.approved = 1 ORDER BY astatus.onlinestatus DESC");
if (mysql_num_rows($friendlook)) {
$row = mysql_fetch_assoc($friendlook);
$rows[] = $row;
print json_encode($rows);
} else {
$arr = array("error" => "Your friends are not online");
print json_encode($arr);
}
return;
}
$arr = array("error" => "No Friends?<br/>Search above for New users or invite some friends.");
print json_encode($arr);
}
Комментарии:
1. Еще одна вещь: используйте SELECT COUNT(*) вместо SELECT *
Ответ №3:
Не совсем ответ на ваш вопрос, но, возможно, вы хотите использовать что-то вроде
public function friendsOutputAsJSON($userid)
{
$this->userid = $userid;
$result = mysql_query("
SELECT
friend.to_userid,
info.username, info.firstname, info.lastname, info.status,
astatus.onlinestatus
FROM
user_contact as friend
LEFT JOIN
user_info as info
ON
friend.to_userid = info.id
LEFT JOIN
user_online as astatus
ON
friend.to_userid = astatus.userid
WHERE
friend.to_userid = info.id
AND friend.from_userid = '". mysql_real_escape_string($userid). "'
AND friend.approved = 1
ORDER BY
astatus.onlinestatus DESC
");
if ( !$result ) {
yourErrorHandler();
}
$rows = array();
while( $row=mysql_fetch_assoc($result) ) {
$rows[] = $row;
}
if( empty($rows) )
{
$rows = array("error" => "No Friends?<br/>Search above for New users or invite some friends.");
}
print json_encode($arr);
}
т.е.
- не выполняет дополнительный запрос, чтобы проверить, есть ли какие-либо записи (которые должны использовать Count(*), если вы хотите его сохранить)
- извлекать все записи, а не только первую
- проверка, были ли извлечены некоторые записи, вместо этого используя mysql_num_rows
- имея только один возврат / печать «точки выхода» для функции
- (возможно, предотвращение SQL-инъекций — зависит от того, каким может быть $userid / как он проверяется перед вызовом функции)
Ответ №4:
я думаю, что json_encode() завершается с ошибкой.
я советую вам проверить тип ошибки :
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - No errors';
break;
case JSON_ERROR_DEPTH:
echo ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
echo ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
echo ' - Unknown error';
break;
}
Ответ №5:
Чтобы избежать печати false, используйте if (mysql_num_rows($friendlook))
(в части $ friendlook), чтобы проверить, есть ли результаты, прежде чем пытаться что-либо напечатать.
Если результатов нет, ничего не будет напечатано. и у вас не будет этой досадной проблемы.
Примечание по производительности: не используйте print, вместо этого используйте echo.
Комментарии:
1. Есть ли какая-либо разница между print / echo вообще? Мне сказали использовать print, а не echo. 😉
2. @RussellHarrower print возвращает логическое значение true, echo не имеет возвращаемого значения. Это сэкономит процессорное время и повысит производительность при интенсивно используемых сценариях.
3. Кто бы ни проголосовал против, пожалуйста, удалите этот отрицательный голос. Вы понижаете голос, когда ответ бесполезен, а не когда вы не понимаете его часть. Что также не имело большого отношения к самому решению. Решение, которое я дал, действительно работает.
4. @Mario — Даже если вы печатаете в цикле 100000, вы не сможете определить, есть ли разница во времени выполнения. Поэтому я бы поместил этот совет в конце ответа, на данный момент это может означать, что это причина ошибки.
5. @martinstoeckli Спасибо за предложение, я отредактировал соответствующим образом.