php 不会为新用户显示所需的数据,因为这些数据是从前一个用户该高速缓存中获取的

rta7y2nd  于 2023-08-02  发布在  PHP
关注(0)|答案(1)|浏览(84)

我做了一个自定义模块,显示特定城市的天气。
但我在代码审查后得到了这些评论:

1.有趣的问题,如果网站首先来自伦敦市的人,然后是巴黎,你的缓存数据会发生什么?

据我所知,这意味着一个来自巴黎的人,当他进入网站时,将看到伦敦的天气,因为它将该高速缓存中取出。但是我把数据放在该高速缓存中,这样就不会有太多的请求,我做了一次请求,把数据放进缓存,下一次我从缓存中取数据。

2.在小函数中,您调用了http://ip-api.com/json/端点两次。当网站每分钟有1000人访问时会发生什么?

在这里,我不明白问题是什么。如果这意味着资源的连接限制将被耗尽,那么如何解决这个问题?在getCity()函数中,将数据放入该高速缓存的方式与我在build()函数中所做的相同?但是,与第一条注解中相同的问题出现了,如果来自另一个城市的人访问该网站,则将从该高速缓存中获取数据(伦敦市的名称),而不是他真实的的城市名称。那该怎么办呢?
你能告诉我我的代码需要修改什么吗?下面我将为我的php文件写一个稍微精简的代码。完整版本在这里:https://phpsandbox.io/n/sweet-forest-1lew-1wmof

// ....
use Drupal\Core\Cache\CacheBackendInterface;
use GuzzleHttp\Client;

//....

  public function getCity() {

    $ip = '193.62.157.66';  // static because for testing

    try {
      $response_ip = $this->httpClient->get('http://ip-api.com/json/' . $ip);
      $response_data_ip = $response_ip->getBody();
      $data_ip = json_decode($response_data_ip);

      if ($data_ip->status == 'success') {
        return $data_ip->city;
      }
      else {
        return $this->configFactory->get('sydneypro_weather.settings')->get('weather_city');
      }

    }
    catch (RequestException $e) {
      return FALSE;
    }

  }

  public function build() {
    $client = $this->httpClient;
    $api_key = $this->configFactory->get('sydneypro_weather.settings')->get('weather_api_key');
    $cid = 'sydneypro_weather';
    $weather_config = $this->configFactory->get('sydneypro_weather.settings');

    if (!$weather_config) {
      $this->logger->get('sydneypro_weather')->error('Config "sydneypro_weather.settings" is missing4');
      return [];
    }

    if (empty($api_key) || empty($this->getCity())) {
      return [
        '#type' => 'markup',
        '#markup' => $this->t('Please enter your API key and City in the Admin panel to see the weather'),
      ];
    }

    try {
      if ($cache = $this->cacheBackend->get($cid)) {
        $data = $cache->data;
      }
      else {
        $response = $client->get('http://api.openweathermap.org/data/2.5/weather?q=' . $this->getCity() . ',&appid=' . $api_key . '&units=metric');
        $response_data = $response->getBody();
        $data = json_decode($response_data);
        $this->cacheBackend->set($cid, $data, $this->time->getRequestTime() + 21600);
      }

      $build = [
        '#theme' => 'weather_block',
        '#data' => $data,
        '#attached' => [
          'library' => [
            'sydneypro_weather/sydneypro_weather',
          ],
        ],
      ];

      return $build;

    }
  // ....

字符串

0mkxixxg

0mkxixxg1#

1.您需要根据给定的城市显示一些数据,因此应该使用允许检索特定城市数据的缓存id,以每个城市为基础缓存数据。换句话说,$cid必须包含城市名称或标识符。

$city = $this->getCity();
$cid = 'sydneypro_weather:' . $city;

字符串
1.为$city使用变量可以防止getCity()被调用两次。您也可以设置一个缓存,将IP地址Map到相应的城市,但这可能不是一个好主意,因为填充该高速缓存表的(可能的)不同地址的数量可能非常高。
另一种方法是使用JavaScript和/或cookie从用户的浏览器中获取用户的地区/城市,并仅为那些不共享其位置的用户调用API。

相关问题