Kann ich mit PHP eine foreach-Anweisung in einen Transienten einfügen?
P粉352408038
P粉352408038 2024-04-03 17:12:43
0
2
500

Ich arbeite in WP mit PHP und versuche, die Ladezeit einer Funktion zu reduzieren, die viele Daten abruft. Ich dachte, Transients würden funktionieren, und (wie unten gezeigt) habe ich die Kursabfrage in Transients geladen, aber sie funktioniert nicht mit der foreach-Anweisung, oder besser gesagt, ich weiß nicht, wie ich sie richtig einrichten soll, damit sie funktioniert.

Der wichtigste Codeteil, der alles verlangsamt, ist die foreach-Anweisung, die die Vimeo-Video-ID jedes Themas abruft, sie durch die Funktion vimeo_api() laufen lässt, dann die Dauer des Videos abruft und sie dann an die Themen-ID anhängt innerhalb eines Arrays.

Technisch gesehen muss ich nicht über die Funktion get_vimeo_duration_all_courses() verfügen (Sie ruft alle Kurse/Lektionen/Themen auf), sondern muss beim Laden einfach die Vimeo-ID von jedem Thema abrufen. So habe ich angefangen und es funktioniert, aber leider funktioniert es nicht erhöht die Ladezeit meiner Seite. Meine Idee ist, dass ich die Funktion vimeo_api() nicht jedes Mal aufrufen muss, wenn ich die Videodauer abrufen möchte, wenn ich alle Dauern innerhalb des Arrays laden und jede Dauer an die Themen-ID anhängen kann. Ich könnte die Variable $vimeo auch einmal am Tag aktualisieren und dann die Variable $vimeo nach der Themen-ID durchsuchen, um die Vimeo-Dauer zu erhalten.

Ich würde also wohl gerne wissen, ob ich in die richtige Richtung gehe oder ob Sie einen besseren Weg kennen?

Gibt es eine Möglichkeit, die Variable $vimeo und alle darin enthaltenen Werte zu speichern, sodass die Funktion vimeo_api() nicht jedes Mal ausgeführt werden muss?

Jede Hilfe wäre großartig! Danke

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
}

Hier bekomme ich die Vimeo-API und gebe die Videodauer zurück

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粉352408038
P粉352408038

Antworte allen(2)
P粉757432491

将 WP_Query 返回的对象存储在瞬态中是没有意义的。该对象用于控制 WordPress 循环。但像 all_video_durations 那样使用瞬态确实有意义,非常有意义。瞬态将持久保存任何 php 数组或对象的数据。

瞬态非常适合缓存难以获取的值,例如从视频服务 API 获取的值。它们适用于所有 WordPress 安装,并且在具有持久对象缓存的安装中运行速度更快。

您可能希望对每个视频项目使用单独的瞬态,而不是将它们捆绑在一起。如果您添加新项目,这将使您的代码工作得更好一些。

(此外,如果您使用 WordPress 的内置请求 class 而不是 cURL,您的代码将在无法正确处理 cURL 的托管服务中的 WordPress 安装上运行。如果您将 cURL 代码提交到插件存储库,审阅者将要求您替换它。有时问我怎么知道这一点:-)

P粉760675452

感谢您的建议,它们确实帮助我朝着正确的方向前进。我最终删除了调用所有课程的函数,并内置了一个托管所有 Vimeo ID 和持续时间的缓存文件。然后,当我调用该函数时,它首先搜索缓存文件,如果找到 Vimeo ID,则获取持续时间,但如果找不到 ID,则运行 API。

下面是最终的代码...

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";
        } 
    }
}
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage