简体   繁体   中英

Search within array or compare values

To improve my php experiences I have written a small movie databse with the TMDB API.

Now I have data from the API and data from own codings. I have a database movieSeen where people can save movies they have already seen.

 global $pdo;
 $stmt = $pdo->prepare("SELECT * FROM movieSeen WHERE user_id = '" . $_SESSION['id'] . "'");
 $stmt->execute();

 foreach ($stmt as $row ) {
    echo $row['movie_id'] . ', ';
 } // outputs the IDs of the movies already seen. here: 157, 189, 298, 456

Now I have a API Call where I load all movies from a specific director.

    $url = "https://api.themoviedb.org/3/person/" . $personID . "/movie_credits?api_key=" . $apiKey . "&" . $language . "";// path to your JSON file
    $data = file_get_contents($url); // put the contents of the file into a variable
    $personCareer = json_decode($data); // decode the JSON feed

    foreach ($personCareer->crew as $showCrewDetails) { //output of the movies of a specific director
        echo '<tr>';
            echo '<td><a href="getMovie.php?movieID=' . $showCrewDetails->id . '">' . $showCrewDetails->title . ' ' . $showCrewDetails->id . ' (' . substr($showCrewDetails->release_date, 0, 4) . ')</a></td>';
            echo '<td><span class="badge badge-danger">Movie Seen</span></td>';
            echo '<td>' . $showCrewDetails->job . '</td>';
        echo '</tr>';
    }

Every movie which has alredy be seen should be checked as seen in this list. So I have to check if the IDs from my database are included in the API call.

I think I have to use something like in_array or array_search to see if $showCrewDetails->id is equal to $row['movie_id'] .

But I don't know how to exactly do it. I am thankful for every hint.

I would do something like this:

/**
 * @param int $user_id DB user ID
 * @param PDO $pdo
 * @return int[] User movie IDs
 */
function getUserSeenMovieIds(int $user_id, PDO $pdo) : array {
    $stmt = $pdo->prepare('SELECT movie_id FROM movieSeen WHERE user_id = :user_id');
    $stmt->execute([':user_id' => $user_id]);
    return $stmt->fetchAll(PDO::FETCH_COLUMN, 0) ?: [];
}

/**
 * @return array Response from api.themoviedb.org/3/person/{int}/movie_credits
 */
function getMovieCredits(int $personID, string $apiKey, string $language) : array {
    $query = http_build_query([
        'api_key' => $apiKey,
        'language' => $language,
    ]);
    $url = 'https://api.themoviedb.org/3/person/' . $personID . '/movie_credits?' . $query;
    $data = file_get_contents($url);
    $credits = json_decode($data, true);
    if (!is_array($credits)) {
        throw new \RuntimeException("Failed decoding response $data from URL $url");
    }

    return $credits;
}

/**
 * @param array $credits Response from api.themoviedb.org/3/person/{int}/movie_credits
 * @param int[] $movie_ids
 * @return array Crew details from the response filtered by the movie IDs
 */
function getMovieCrewDetails(array $credits, array $movie_ids) : array
{
    $reference = array_flip($movie_ids);
    $credits = [];

    foreach ($credits['crew'] as $crew) {
        $id = $crew['id'];
        if (isset($reference[$id])) {
            $credits[] = $crew;
        }
    }

    return $credits;
}

////////////////////////////////////////////////////////////////////////////////

$movie_ids = getUserSeenMovieIds($user_id, $pdo);
$credits = getMovieCredits($personID, $apiKey, $language);
foreach (getMovieCrewDetails($credits, $movie_ids) as $crew) {
    // TODO: Print $crew
}

The code above avoids nested loop (which would result in O(n*m) complexity) in getMovieCrewDetails by using a hash table $reference . Hash tables are O(1) average case complexity, so using them for moderate data sets is generally a good idea.

There is a number of other things to note:

  • do use PDO placeholders, since they free you from the need to escape the input;
  • do not use global , since you can easily avoid pollution of the global name space by using functions, classes and techniques like dependency injection;
  • always check for the values functions return; otherwise, you are risking to catch an unexpected runtime error or bug (I've put some error checking into the code, but you should really check every function call.)

if you have $showCrewDetails->id is multiple value.

use foreach

foreach ($showCrewDetails as $key => $val) {
   $id_fromapi = $val->id;
   $stmt = $pdo->prepare("SELECT *FROM movieSeen WHERE user_id ='".$id_fromapi ."'");
   $stmt->execute();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM