猿问

是否有更好的循环遍历这些 PHP 代码的方法,也许使用 foreach 循环?

我file_get_contents用来获取远程定价(每天更新),substr用来只保留我想要的部分(从输出中剥离货币符号和其他数据,只保留数字)并file_put_contents用来将它存储到我引用的缓存目录中到以后。


这就是我现在所拥有的:-


<?php


$cacheDirectory = $_SERVER['DOCUMENT_ROOT'] . '/cache/';


// Small Plan - US

$cachefile_SM_US = $cacheDirectory . 'SM_US.cache';


if(file_exists($cachefile_SM_US)) {

    if(time() - filemtime($cachefile_SM_US) > 1600) {

        // too old , re-fetch

       $cache_SM_US = file_get_contents('https://remotedomain.com/?get=price&product=10&currency=1');

        $substr_SM_US = substr($cache_SM_US,17,2);

        file_put_contents($cachefile_SM_US, $substr_SM_US);

        } else {

            // cache is still fresh

    }

} else {

    // no cache, create one

    $cache_SM_US = file_get_contents('https://remotedomain.com/?get=price&product=10&currency=1');

    $substr_SM_US = substr($cache_SM_US,17,2);

    file_put_contents($cachefile_SM_US, $substr_SM_US);

}


// Large Plan - US

$cachefile_LG_US = $cacheDirectory . 'LG_US.cache';


if(file_exists($cachefile_LG_US)) {

    if(time() - filemtime($cachefile_LG_US) > 1600) {

        // too old , re-fetch

        $cache_LG_US = file_get_contents('https://remotedomain.com/?get=price&product=20&currency=1');

        $substr_LG_US = substr($cache_LG_US,17,2);

        file_put_contents($cachefile_LG_US, $substr_LG_US);

    } else {

        // cache is still fresh

    }

} else {

    // no cache, create one

    $cache_LG_US = file_get_contents('https://remotedomain.com/?get=price&product=20&currency=1');

    $substr_LG_US = substr($cache_LG_US,17,2);

    file_put_contents($cachefile_LG_US, $substr_LG_US);

}

当只有两种产品 (10和20) 和两种货币 (1和2) 时,这种手动方式有效,因为我只需要这样做 4 次就可以获得我需要的所有定价。


但是,我打算将产品数量显着扩大到至少 12 种产品和 9 种货币,因此手动完成它们是不现实的。


我相信这可以通过 PHP foreach 循环更有效地完成,但我尝试了几天但没能成功,这可能是因为我对这个概念的理解较弱。


心有法竹
浏览 137回答 2
2回答

Smart猫小萌

绝对地。看看这个例子:)<?php declare(strict_types=1);interface CacheNormalizer{&nbsp; &nbsp; public function normalize(string $text): string;}interface PlanDomainToCache{&nbsp; &nbsp; public function buildUrl(Plan $plan): string;}final class CachedRemoteSiteManager{&nbsp; &nbsp; /** @var int Time To Live Cache */&nbsp; &nbsp; private $timeToLive;&nbsp; &nbsp; /** @var CacheNormalizer */&nbsp; &nbsp; private $cacheNormalizer;&nbsp; &nbsp; /** @var PlanDomainToCache */&nbsp; &nbsp; private $planDomainToCache;&nbsp; &nbsp; public function __construct(&nbsp; &nbsp; &nbsp; &nbsp; int $timeToLive,&nbsp; &nbsp; &nbsp; &nbsp; CacheNormalizer $cacheNormalizer,&nbsp; &nbsp; &nbsp; &nbsp; PlanDomainToCache $planDomainToCache&nbsp; &nbsp; ) {&nbsp; &nbsp; &nbsp; &nbsp; $this->timeToLive = $timeToLive;&nbsp; &nbsp; &nbsp; &nbsp; $this->cacheNormalizer = $cacheNormalizer;&nbsp; &nbsp; &nbsp; &nbsp; $this->planDomainToCache = $planDomainToCache;&nbsp; &nbsp; }&nbsp; &nbsp; public function updateIfNecessary(Plan $plan): void&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if ($this->shouldCreateOrUpdateCache($plan)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this->createOrUpdateCache($plan);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private function shouldCreateOrUpdateCache(Plan $plan): bool&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return !file_exists($plan->cacheDirectory())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || time() - filemtime($plan->cacheDirectory()) > $this->timeToLive;&nbsp; &nbsp; }&nbsp; &nbsp; private function createOrUpdateCache(Plan $plan): void&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $urlToCache = $this->planDomainToCache->buildUrl($plan);&nbsp; &nbsp; &nbsp; &nbsp; $textToCache = file_get_contents($urlToCache);&nbsp; &nbsp; &nbsp; &nbsp; file_put_contents(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $plan->cacheDirectory(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this->cacheNormalizer->normalize($textToCache)&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}final class Plan{&nbsp; &nbsp; /** @var string */&nbsp; &nbsp; private $cacheDirectory;&nbsp; &nbsp; /** @var int */&nbsp; &nbsp; private $product;&nbsp; &nbsp; /** @var int */&nbsp; &nbsp; private $currency;&nbsp; &nbsp; public function __construct(string $cacheDir, int $product, int $currency)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->cacheDirectory = $cacheDir;&nbsp; &nbsp; &nbsp; &nbsp; $this->product = $product;&nbsp; &nbsp; &nbsp; &nbsp; $this->currency = $currency;&nbsp; &nbsp; }&nbsp; &nbsp; public function cacheDirectory(): string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->cacheDirectory;&nbsp; &nbsp; }&nbsp; &nbsp; public function product(): int&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->product;&nbsp; &nbsp; }&nbsp; &nbsp; public function currency(): int&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->currency;&nbsp; &nbsp; }}// Usage example:$cacheDirectory = $_SERVER['DOCUMENT_ROOT'] . '/cache/';$productA = 10;$productB = 20;$USD = 1;$EUR = 2;/** @var Plan[] */$plansToCache = [&nbsp; &nbsp; new Plan($cacheDirectory . 'SM_US.cache', $productA, $USD),&nbsp; &nbsp; new Plan($cacheDirectory . 'LG_US.cache', $productB, $USD),&nbsp; &nbsp; new Plan($cacheDirectory . 'SM_EU.cache', $productA, $EUR),&nbsp; &nbsp; new Plan($cacheDirectory . 'LG_EU.cache', $productB, $EUR),];$cacheManager = new CachedRemoteSiteManager(&nbsp; &nbsp; $cacheTtl = 1600,&nbsp; &nbsp; new class implements CacheNormalizer {&nbsp; &nbsp; &nbsp; &nbsp; public function normalize(string $text): string&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return substr($text, 17, 2);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; },&nbsp; &nbsp; new class implements PlanDomainToCache {&nbsp; &nbsp; &nbsp; &nbsp; public function buildUrl(Plan $plan): string&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return sprintf(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'https://remotedomain.com/?get=price&product=%d&currency=%d',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $plan->product(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $plan->currency()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });foreach ($plansToCache as $plan) {&nbsp; &nbsp; $cacheManager->updateIfNecessary($plan);}正如您在底部看到的,在“使用示例”中,我提取了所有细节(几乎所有细节),因此我们可以轻松定义:我们要如何规范化缓存数据(使用 CacheNormalizer)我们要如何构建要缓存的 URL(使用 PlanDomainToCache)。更新:如果您想了解如何从结束代码中提取/解耦每个细节,即使对于“持久性”层也向上反转依赖关系:https ://gist.github.com/Chemaclass/01d3f42685ff69f6897192202a32014d

ITMISS

如果我正确地解释了代码,您想要查找两种货币的两种产品。这可以在您定义产品和货币后使用嵌套的 foreach 循环来完成。$cacheDirectory = $_SERVER['DOCUMENT_ROOT'] . '/cache/';$url = 'https://remotedomain.com/?get=price';const MAX_CACHE_TIME = 1600;// Optional$output = [];$productList = [&nbsp; &nbsp; [&nbsp; &nbsp; &nbsp; &nbsp; 'id'&nbsp; &nbsp;=> 10,&nbsp; &nbsp; &nbsp; &nbsp; 'name' => 'SM',&nbsp; &nbsp; ],&nbsp; &nbsp; [&nbsp; &nbsp; &nbsp; &nbsp; 'id'&nbsp; &nbsp;=> 20,&nbsp; &nbsp; &nbsp; &nbsp; 'name' => 'LG',&nbsp; &nbsp; ]];$currencies = [&nbsp; &nbsp; 'US' => 1,&nbsp; &nbsp; 'EU' => 2,];foreach ($productList as $product) {&nbsp; &nbsp; foreach ($currencies as $currencyName => $currencyId) {&nbsp; &nbsp; &nbsp; &nbsp; $cacheFile = $cacheDirectory . $product['name'] . '_' . $currencyName . '.cache';&nbsp; &nbsp; &nbsp; &nbsp; if (!file_exists($cacheFile) || filemtime($cacheFile) > MAX_CACHE_TIME) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // No cache or too old&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $data = file_get_contents($url . '&product=' . $product['id'] . '&currency=' . $currencyId);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $relevantData = substr($data, 17, 2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; file_put_contents($cacheFile, $relevantData);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Optional, put the data in an array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $output[$product['id']][$currencyId] = $relevantData;&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $output[$product['id']][$currencyId] = file_get_contents($cacheFile);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}// Read outputwith $output[10]['US'] for example
随时随地看视频慕课网APP
我要回答