3

我有一个脚本,通过 RESTful Web 服务将订单数据发送到第 3 方系统。该系统要求每个请求都发送一个唯一 ID,该 ID 从下一个请求开始自动递增。

我已经通过在 Magento 的表中为此添加一个变量来实现这一点core_config_data,并且作为我的代码的一部分,调用下面的函数来获取 ID 的下一个值,为下一个请求递增它。

class MyProject
{
    public function getNextApiId() {
        // Get the next ID.
        $id = Mage::getStoreConfig('myproject/next_api_id');

        // Increment the stored value for next time.
        $nextId = $id + 1; // change $id++ by $id + 1 otherwise the result of $nextId = $id - 1;
        Mage::getModel('core/config')->saveConfig('myproject/next_api_id',$nextId);

        // Refresh the config.
        Mage::getConfig()->cleanCache();
        Mage::getConfig()->reinit();

        // Return the ID.
        return $id;
    }
}

如果我用我的脚本发送一个请求,这工作正常 - 值递增,下一个 ID 用于脚本的下一次执行。

但是,如果我在同一脚本执行中循环处理多个请求,则该值似乎已被缓存。下面的代码应该说明一般流程,尽管为了简洁起见我已经减少了它:

function sendRequest($item) {
    $apiId = $MyProject->getNextApiId();

    // Build and send request body
}

foreach($items as $item) {
    sendRequest($item);
}

这将导致初始 ID 号用于所有$items.

和尝试刷新配置缓存似乎cleanCache()根本reinit()不起作用。关于如何阻止值被缓存的任何想法?

4

5 回答 5

6

必须以不同的方式清理缓存,您必须重置存储的缓存并再次初始化它,从而导致循环。如果你没有循环,它也会被清理,但它需要商店的第二个 url 请求,它将初始化缓存。

试试这个:

function getNextApiId() {
    // Get the next ID.
    $id = Mage::getStoreConfig('myproject/next_api_id');

    // Increment the stored value for next time.
    $nextId = $id + 1;

    Mage::getConfig()->saveConfig('myproject/next_api_id',$nextId);

    // Refresh the config.
    Mage::app()->getStore()->resetConfig();

    // Return the ID.
    return $id;
}
于 2013-01-04T17:13:56.850 回答
4

如果您只需要将唯一的 id 传递给 api,为什么还要费心费力 - 读取和写入 db、清除配置缓存等?

在 PHP 中有很多方法可以做到这一点,这里是一种:

$uniqueId = uniqid();

http://php.net/manual/en/function.uniqid.php

否则,如果您必须使用问题中的方法创建您的 ID,请确保您正确保存配置:

Mage::getConfig()
    ->saveConfig('myproject/next_api_id', $nextId)
    ->cleanCache();
Mage::app()->reinitStores();
于 2013-01-04T17:19:28.013 回答
4

Magento 配置适用于不经常更改的值,这些值会改变某物的行为。将这个值存储在配置中不仅不符合目的,而且会给站点带来性能问题。每次清除配置缓存时,站点都必须将配置文件中继到存储在缓存中的缓存 XML 文档中,这会给站点的加载时间带来不必要的延迟。

我的建议是执行以下操作之一:

一种。使用基于包含您的进程 ID 和 unix 时间戳(微秒)的生成模式的 UID。

湾。使用核心变量模型将您的值存储在:Mage::getModel('core/variable')->loadByCode('myproject_next_api_id');

我对选项“b”的警告是,如果您有可能此脚本可能同时运行多个实例,您遇到竞争条件,这需要将 ID 存储在您通过自定义原子更新查询更新的数据库中.

于 2013-01-07T14:38:08.827 回答
1

这是一个简单的替代方案:

protected function _getLastId()
{
    $id = Mage::app()->useCache('config') ?
        Mage::getResourceModel('core/config_data_collection')
            ->addFieldToFilter('path', self::XML_PATH_LAST_ID)
            //->addFieldToFilter('scope', $scope)
            //->addFieldToFilter('scope_id', $scopeId)
            ->getFirstItem()
            ->getValue() :
        Mage::getStoreConfig(self::XML_PATH_LAST_ID);
    return (int) $id;
}
于 2016-09-08T09:41:22.027 回答
0

选择的答案以及许多其他涉及清除缓存的答案是完全可耻的,因为这Mage::app()->getStore()->resetConfig();将导致Mage::getConfig()->reinit();您最应该调用的答案...永远不会!

它将触发 Magento 完全重新解析 XML 配置,这非常,随着插件及其配置文件数量的增加,更是如此。

我见过一些插件开发人员复制粘贴这样的东西,最终给使用这些插件的人带来了巨大的性能问题。不仅通过使用这些代码(也如此),而且还巧妙地管理填充这些代码以在每个请求时调用,有效地导致配置缓存效率下降到 0!

如果您可以简单地更新更改的内容,为什么要清除整个配置缓存?

Mage::app()->getStore()->setConfig('foo', 'bar'); 
Mage::getConfig()->saveConfig('foo', 'bar')->saveCache();

第一行仅更新请求生命周期的配置项(运行时缓存)

第二行确保将相同的内容保存到core_config_data并更新缓存。

但无论哪种方式,@davidalger 的回答都正确地指出这core_config_data意味着很少更改数据。

于 2019-10-31T11:36:29.873 回答