首頁  >  問答  >  主體

使用 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粉352408038179 天前343

全部回覆(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
  • 取消回覆