Maison  >  Questions et réponses  >  le corps du texte

En utilisant PHP, puis-je mettre une instruction foreach dans un transitoire ?

Je travaille dans WP en utilisant PHP et j'essaie de réduire le temps de chargement d'une fonction qui récupère beaucoup de données. Je pensais que les transitoires fonctionneraient et (comme indiqué ci-dessous) j'ai chargé la requête de cours dans les transitoires, mais cela ne fonctionne pas avec l'instruction foreach, ou plutôt, je ne sais pas comment la configurer correctement pour la faire fonctionner.

Le principal morceau de code qui ralentit tout est l'instruction foreach, qui obtient l'identifiant de la vidéo Vimeo de chaque sujet, l'exécute via la fonction vimeo_api(), puis obtient la durée de la vidéo, puis l'ajoute à l'identifiant du sujet. à l'intérieur d'un tableau.

Techniquement, je n'ai pas besoin d'avoir la fonction get_vimeo_duration_all_courses() (Elle appelle tous les cours/leçons/sujets) mais il suffit d'obtenir l'identifiant Vimeo de chaque sujet au chargement. C'est comme ça que j'ai commencé et ça marche, mais malheureusement ça augmente le temps de chargement de ma page. Mon idée est que si je peux charger toutes les durées dans le tableau et ajouter chaque durée à l'ID du sujet, je n'ai pas besoin d'appeler la fonction vimeo_api() à chaque fois que je veux obtenir la durée de la vidéo. Je pourrais également mettre à jour la variable $vimeo une fois par jour, puis rechercher dans la variable $vimeo l'ID du sujet pour obtenir la durée de vimeo.

Alors je suppose que j'aimerais savoir si je vais dans la bonne direction ou si vous connaissez une meilleure façon ?

Existe-t-il un moyen de stocker la variable $vimeo et toutes les valeurs qu'elle contient afin que la fonction vimeo_api() ne doive pas être exécutée à chaque fois ?

Toute aide serait formidable ! Merci

function get_vimeo_duration_all_courses($vimeo)
{
    $courses = get_transient('all_courses'); 
    if (false === $courses) {

        $courses = new WP_Query(array(
            'posts_per_page' => -1,
            'post_type'  => 'sfwd-courses',
            'no_found_rows' => true,
            'cache_results' => true,
            'ignore_sticky_posts'  => true,
            'fields' => 'ids',
        )); //Grabs all the courses

        set_transient('all_courses', $courses, (24 * HOUR_IN_SECONDS));
    }

    $vimeo = get_transient('all_vimeo_durations');
    if (false === $vimeo) {
        $vimeo = array();

        foreach ($courses->posts as $course_id) {
            $lessons = learndash_course_get_lessons($course_id); //Gets all the lessons under the course
            
            foreach ($lessons as $lesson) {
                $topics = learndash_course_get_topics($course_id, $lesson->ID); //Gets all the topics under the lesson
                
                foreach ($topics as $topic) {
                    $vimeoVideo = get_field('lesson_video', $topic->ID); 
                    
                    if (!empty($vimeoVideo)) { //Looks at each topic and determines whether it has a vimeo video or not
                        $vimeoDuration = vimeo_api($vimeoVideo); //If true, it runs the vimeo ID through the vimeo_api() function (THIS IS WHERE IT BECOMES SLOW)
                        $vimeo[$topic->ID] = $vimeoDuration;
                    }
                }

            }

        }

        set_transient('all_vimeo_durations', $vimeo, (24 * HOUR_IN_SECONDS));
    }

   return $vimeo;
}


function show_vimeo_duration($topicID) {
    return $vimeo[$topicID]; //Returns the value of the vimeo_api() function that matches the topicID
}

C'est ici que j'obtiens l'API Vimeo et renvoie la durée de la vidéo

function vimeo_api($id)
{
    try {
        $authorization = 'CODELEFTOUTONPURPOSE';
        $ch = curl_init();

        curl_setopt_array($ch, array(
            CURLOPT_URL => "https://api.vimeo.com/videos/$id?fields=duration",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_HTTPHEADER => array(
                "authorization: Bearer {$authorization}",
                "cache-control: no-cache",
            ),
        ));

        $res = curl_exec($ch);
        $obj = json_decode($res, true);
        return $obj['duration'];//Returns the duration of the video
    } catch (Exception $e) {
        return "0";
    }
}

P粉352408038P粉352408038179 Il y a quelques jours344

répondre à tous(2)je répondrai

  • P粉757432491

    P粉7574324912024-04-04 10:04:36

    Il ne sert à rien de stocker l'objet renvoyé par WP_Query dans un transitoire. Cet objet est utilisé pour contrôler les boucles WordPress. Mais utiliser des transitoires comme all_video_durations a tout à fait du sens. Transient conservera les données de n'importe quel tableau ou objet php.

    Les transitoires sont parfaits pour mettre en cache des valeurs difficiles à obtenir, telles que celles d'une API de service vidéo. Ils fonctionnent sur toutes les installations WordPress et s'exécutent plus rapidement dans les installations avec mise en cache d'objets persistante.

    Vous souhaiterez peut-être utiliser des transitoires distincts pour chaque projet vidéo plutôt que de les regrouper. Cela permettra à votre code de fonctionner un peu mieux si vous ajoutez de nouveaux projets.

    (De plus, si vous utilisez la classe Requests intégrée de WordPress au lieu de cURL, votre code s'exécutera sur une installation WordPress sur un service d'hébergement qui ne gère pas correctement cURL. Si vous soumettez votre code cURL à un référentiel de plugins, évaluateurs Il vous sera demandé de le remplacer, demandez-moi parfois comment je le sais :-)

    répondre
    0
  • P粉760675452

    P粉7606754522024-04-04 00:29:41

    Merci pour vos suggestions, elles m'ont vraiment aidé à avancer dans la bonne direction. J'ai fini par supprimer la fonction qui appelle toutes les classes et intégré un fichier cache qui héberge tous les identifiants et durées Vimeo. Ensuite, lorsque j'appelle la fonction, elle recherche d'abord le fichier cache et si elle trouve l'ID Vimeo, elle obtient la durée, mais si elle ne trouve pas l'ID, elle exécute l'API.

    Voici le code final...

    function vimeo_api($vimeoID)
    {
        $vimeoCacheUrl = WP_CONTENT_DIR . '/cache/vimeo-duration-cache.txt';
        $newData = '';
        $vimeoData = array();
        $vimeoCache = file($vimeoCacheUrl);
        $vimeoCache = array_unique($vimeoCache);
        file_put_contents($vimeoCacheUrl, implode($vimeoCache), LOCK_EX);
        foreach ($vimeoCache as $key => $value) {
            $data = explode(',', $value, 2);
            $vimeoData[$data[0]] = $data[1];
        }
    
        if (isset($vimeoData[$vimeoID])) {
            return $vimeoData[$vimeoID];
        } else {
            try {
                $authorization = 'XXXX';
                $ch = curl_init();
    
                curl_setopt_array($ch, array(
                    CURLOPT_URL => "https://api.vimeo.com/videos/$vimeoID?fields=duration",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => "",
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 30,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => "GET",
                    CURLOPT_HTTPHEADER => array(
                        "authorization: Bearer {$authorization}",
                        "cache-control: cache",
                    ),
                ));
    
                $res = curl_exec($ch);
                $obj = json_decode($res, true);
                $newData = $vimeoID . ',' .$obj['duration'];
                file_put_contents($vimeoCacheUrl, str_replace("'", '', var_export($newData, true)) . PHP_EOL, FILE_APPEND | LOCK_EX);
                return $obj['duration'];
            } catch (Exception $e) {
                return "0";
            } 
        }
    }

    répondre
    0
  • Annulerrépondre