Странная проблема PHP / MySQL, влияющая на выборку из базы данных только при входе пользователя - PullRequest
1 голос
/ 07 июля 2010

Итак, у меня есть эта функция, которая получает данные из базы данных и отображает их. Функция извлекает из базы данных идентификатор статьи, заголовок статьи и некоторые другие данные.

Когда пользователь не вошел в систему, функция работает хорошо и показывает все данные, но когда пользователь вошел в систему, неожиданно выбирается только заголовок статьи. Все данные находятся в одной базе данных и даже в та же таблица, но выбран только идентификатор статьи !!

Примечания:

  1. На моем локальном хосте этого не происходит.
  2. Мой хост - ipage.com, и чтобы заставить сеансы php работать, мне нужно добавить session_save_path (// path) перед session_start () (я не знаю, связано ли это с проблемой)

Обновление:

Это ошибка: Warning: implode() [function.implode]: Invalid arguments passed in /path

Это функция:

function getNowPlaying($stmt) {

    $sql = 'SELECT movies.imdbID, movies.title FROM movies ORDER BY Rand() LIMIT 15';
    if ($stmt->prepare($sql)) {
        $stmt->bind_result($imdbID, $title);
        $stmt->execute();
        $i = 0;
        while ($stmt->fetch()) {
            $data[$i]["imdb"] = zeroFill($imdbID);
            $data[$i]["title"] = $title;
            $i++;
        }
    }

    for ($i = 0; $i < count($data); $i++) {

        $genres = getGenre($stmt, $data[$i]["imdb"]);
        $data[$i]["genre"] = implode(', ', $genres);

        $data[$i]["poster"] = getPoster($stmt, $data[$i]["imdb"]);
    }

    return $data;
}

function getGenre ($stmt, $id, $db = 'main') {

    if ($db === 'main') {
    $sql = 'SELECT sys_genres.genre FROM sys_genres, movie_genres WHERE sys_genres.genreID = movie_genres.genreID AND movie_genres.imdbID = ?
        ORDER BY movie_genres.genreORDER';
    }

    else if ($db === 'inp') {
    $sql = 'SELECT sys_genres.genre FROM sys_genres, inp_movie_genres WHERE sys_genres.genreID = inp_movie_genres.genreID AND inp_movie_genres.imdbID = ?
        ORDER BY inp_movie_genres.genreORDER';
    }

    if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $id);
    $stmt->bind_result($genres);
    $stmt->execute();

    while ($stmt->fetch()) {
        $data[] = $genres;
    }
    }

    if (!empty($data)) {
    return $data;
    }
}

Массив Session, когда пользователь вошел в систему:

Array
(
    [xsrf_token] => 13721578024c33e20b2940d3.39161731
    [username] => jonagoldman
    [userID] => 24
    [start] => 1278468629
)

Обновление 2:

Это та часть, которая вызывает проблемы:

В index.php у меня есть это:

if (isset($_SESSION['userID'])) {
    $user_points = getUserPoints($stmt, $_SESSION['userID']);
}


function getUserPoints($stmt, $userid) {

    $sql = 'SELECT points FROM user_points WHERE userID = ? LIMIT 1';

    if ($stmt->prepare($sql)) {
        $stmt->bind_param('i', $userid);
        $stmt->bind_result($data);
        $stmt->execute();
        $stmt->fetch();
    }

    if (!empty($data)) {
        return $data;
    }

}

Эта часть кода вызывает проблему при входе пользователя в систему. Есть идеи?

Ответы [ 2 ]

1 голос
/ 07 июля 2010

Ничто в вашем коде не предполагает что-либо связанное с сеансом, но учтите, что getGenre может возвращать или не возвращать результат. Неясно, что будет делать вызов implode, когда getGenre ничего не вернет. Предупреждение подсказывает мне, что вы не получите никаких жанров назад.

Используя надуманный пример Я могу повторить ваше предупреждение:

function foo(){ }
$bar = foo();
echo implode(', ', $bar);

выдает предупреждение

Предупреждение: implode (): неверные аргументы переданы в ...

Это привело бы меня к мысли, что ваша проблема происходит дальше по цепочке ... то есть вы наблюдаете симптом, а не проблему.

Очевидно, основная проблема заключается в том, что вы передаете $stmt, а не само соединение. Проблемы, которые вы видите, проистекают из кода, который запускается только когда пользователь вошел в систему. Это не означает, что есть проблема с вашей схемой входа в систему, и она полностью не связана с сессиями. Основная проблема заключается в том, что когда пользователь вошел в систему, вы делаете что-то, что вы обычно не делаете с $stmt, в действительности это портит его.

Везде, где вы проходите вокруг $stmt, вы должны передавать ваше соединение $conn (из ваших комментариев выше я знаю, что это $conn). Затем в любом месте, где вам нужен оператор, получите его из соединения, запустив $stmt = $conn->stmt_init();.

0 голосов
/ 07 июля 2010

Я не понимаю, почему это не сработает, когда пользователь вошел в систему, но в коде есть некоторые проблемы.Смотрите мои комментарии:

function getNowPlaying($stmt) {

    $sql = 'SELECT movies.imdbID, movies.title FROM movies ORDER BY Rand() LIMIT 15';
    if ($stmt->prepare($sql)) {
        $stmt->bind_result($imdbID, $title);
        $stmt->execute();
        $i = 0;
        while ($stmt->fetch()) {
            // BAD place to declare $data...what happens if this is **never** executed?
            // $data should be declared outside of the conditional/loop, since you go on to use it after the conditional/loop
            $data[$i]["imdb"] = zeroFill($imdbID);
            $data[$i]["title"] = $title;
            $i++;
        }
    }

    // you should just store count($data) in variable before the for loop, instead of calling count on every iteration of the loop, the size of the array shouldn't change
    for ($i = 0; $i < count($data); $i++) {

        $genres = getGenre($stmt, $data[$i]["imdb"]);
        $data[$i]["genre"] = implode(', ', $genres);
        $data[$i]["poster"] = getPoster($stmt, $data[$i]["imdb"]);
    }

    return $data;
}

function getGenre ($stmt, $id, $db = 'main') {

    // what happens if $db is neither 'main' nor 'inp'?
    if ($db === 'main') {
    $sql = 'SELECT sys_genres.genre FROM sys_genres, movie_genres WHERE sys_genres.genreID = movie_genres.genreID AND movie_genres.imdbID = ?
        ORDER BY movie_genres.genreORDER';
    }

    else if ($db === 'inp') {
    $sql = 'SELECT sys_genres.genre FROM sys_genres, inp_movie_genres WHERE sys_genres.genreID = inp_movie_genres.genreID AND inp_movie_genres.imdbID = ?
        ORDER BY inp_movie_genres.genreORDER';
    }

    if ($stmt->prepare($sql)) {
    $stmt->bind_param('i', $id);
    $stmt->bind_result($genres);
    $stmt->execute();

    while ($stmt->fetch()) {
        // again, declaring variables inside conditionals/loops is bad if you're using those variables outside of the conditional/loop
        $data[] = $genres;
    }
    }

    // and if $data is empty? then what?
    // specific to that error, if you don't return an array, implode() fails
    if (!empty($data)) {
    return $data;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...