搜索

首页  >  问答  >  正文

使用 PHP,我可以将 foreach 语句放入瞬态中吗?

我正在使用 PHP 在 WP 中工作,并试图减少获取大量数据的函数的加载时间。我认为瞬态会起作用,并且(如下所示)我在瞬态下加载了课程查询,但是它不适用于 foreach 语句,或者更确切地说,我不知道如何正确设置它让它发挥作用。

导致一切变慢的主要代码是 foreach 语句,它获取每个主题的 Vimeo 视频 id,通过 vimeo_api() 函数运行它,然后获取视频的持续时间,然后将其附加到内部的主题 id一个数组。

从技术上讲,我不必拥有 get_vimeo_duration_all_courses() 函数(它调用所有课程/课程/主题),而只需在加载时从每个主题中获取 Vimeo ID这就是我一开始的方式,它确实有效,但不幸的是它增加了我的页面加载时间。我的想法是,如果我可以加载数组内的所有持续时间并将每个持续时间附加到主题 ID,那么我就不必每次想要获取视频持续时间时都调用 vimeo_api() 函数。我还可以每天更新一次 $vimeo 变量,然后在 $vimeo 变量中搜索主题 ID 来获取 vimeo 持续时间。

所以我想我想知道我是否朝着正确的方向前进,或者您是否知道更好的方法?

有没有一种方法可以存储 $vimeo 变量及其内部的所有值,以便 vimeo_api() 函数不必每次都运行?

任何帮助都会很棒!谢谢

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
}

这里是我获取 Vimeo api 并返回视频时长的地方

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粉352408038228 天前444

全部回复(2)我来回复

  • P粉757432491

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

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

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

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

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

    回复
    0
  • P粉760675452

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

    感谢您的建议,它们确实帮助我朝着正确的方向前进。我最终删除了调用所有课程的函数,并内置了一个托管所有 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";
            } 
        }
    }

    回复
    0
  • 取消回复