您执行一次性脚本的最佳实践是什么?

时间:2014-01-29 作者:fischi

问题是,我们都遇到过这样的情况,网站上的许多问题都需要这样的解决方案。要么更新数据库,自动插入大量数据,要么转换meta_keys, 或者类似的东西。

当然,在基于最佳实践的运行系统中,这不应该发生

但事实上,我很想听听你对这个问题的个人解决方案,以及你为什么选择自己的解决方案。

问题是

如何在(正在运行的)WordPress安装中实现一次性脚本?

这里的问题主要是因为以下原因:

插入数据的脚本不应运行一次以上,需要大量资源的脚本不应在无法监控的时间运行,它们不应意外运行。我问的原因是我有自己的练习,我将在答案中公布。因为我不知道这是否是最好的解决方案,我想知道你的。此外,这是一个在其他问题中多次被问到的问题,如果有一个资源来收集这些想法,那将是一件好事。

looking forward to learning from you :)

12 个回复
最合适的回答,由SO网友:fischi 整理而成

我自己使用以下组合:

一个专用于一次性脚本的文件,使用瞬态阻止脚本意外运行多次,使用功能管理或用户控制确保脚本仅由我运行

结构

我使用文件(onetime.php) 在我的include文件夹中inc, 包含在functions.php, 使用后从那里删除。

include( \'inc/onetime.php\' );
脚本本身的文件onetime.php 我的职能f711_my_onetime_function() 已放置。因为它可以是任何功能。我假设您的脚本已经过测试,并且工作正常。

为了实现对脚本执行的控制,我使用了

阻止其他用户意外执行我的脚本的功能控制:

if ( current_user_can( \'manage_options\' ) ) // check for administrator rights

if ( get_current_user_id() == 711 ) // check if it is me - I prefer restricting the execution to me, not to all admins.
阻止自己多次意外执行脚本的瞬态过程。

$transient = \'f711_my_onetime_check\';
if ( !get_transient( $transient ) ) // check if the function was not executed.
用于在我的函数中执行脚本的文件f711_my_onetime_function() 看起来是这样的:

$transient = \'f711_my_onetime_check\';
if ( get_current_user_id() == 711 && !get_transient( $transient ) ) {

    set_transient( $transient, \'locked\', 600 ); // lock function for 10 Minutes
    add_action( \'wp_footer\', \'f711_my_onetime_function\' ); // execute my function on the desired hook.

}

function f711_my_onetime_function() {
    // all my glorious one-time-magic.
}
我在检查是否存在后立即设置瞬态的原因是我希望执行函数after 该脚本已被锁定,无法使用两次。

如果我需要函数的任何输出,我可以在页脚中将其作为注释打印出来,有时甚至可以过滤内容。

锁定时间设置为10分钟,但可以根据您的需要进行调整。

清理成功执行脚本后,我将删除includefunctions.php, 并移除onetime.php 从服务器。因为我对瞬态使用了超时,所以我不需要清理数据库,但当然,您也可以在删除文件后删除瞬态。

SO网友:Ravinder Kumar

您也可以这样做:

onetime.php 并在执行后重命名。

if ( current_user_can( \'manage_options\' ) ) {

    if( ! file_exists( \'/path/to/onetime.php\' ) )
      return;
    add_action( \'wp_footer\', \'ravs_my_onetime_function\' ); // execute my function on the desired hook.

}

function ravs_my_onetime_function() {

    // all my glorious one-time-magic.
    include( \'/path/to/onetime.php\' );

   // after all execution rename your file;
   rename( \'/path/to/onetime.php\', \'/path/to/onetime-backup.php\');
}

SO网友:Wyck

我为此创建了一个命令行Phing脚本,除了加载一个外部脚本来运行之外,没有什么特别的。我通过CLI使用它的原因是:

我不希望错误地加载它(需要键入命令)

  • 它是安全的,因为它可以在web根目录之外运行,换句话说,它可以影响WP,但WP无法以任何方式访问脚本
    require(\'..path to ../wp-blog-header.php\');
    //bunch of WP globals
    define(\'WP_USE_THEMES\', false);
    //custom code
    
    因此,您可以使用Phing或PHP CLI并在夜间睡觉。WP-CLI也是一个很好的替代品,尽管我忘记了您是否可以在web根目录之外使用它。

    由于这是一篇很受欢迎的帖子,这里有一个脚本示例:https://github.com/wycks/WordPhing (run.php)

  • SO网友:djb

    在理想情况下,我会使用ssh连接到服务器,并使用wp-cli自己执行该功能。

    但这通常是不可能的,因此我倾向于设置$\\u GET变量并将其挂接到“init”上,例如:

    add_action( \'init\', function() {
        if( isset( $_GET[\'one_time\'] ) && $_GET[\'one_time\'] == \'an_unlikely_string\' ) {
            do_the_one_time_thing();
        }
    });
    
    然后击中

    http://my_blog.com/?one_time=an_unlikely_string
    
    完成后禁用挂钩。

    SO网友:tfrommen

    运行一次性脚本的另一种非常简单的方法是通过MU插件来实现。

    将代码放入一些PHP文件中(例如。,one-time.php) 上载到MU插件文件夹(默认情况下/wp-content/mu-plugins), 调整文件权限,运行插件(即,根据您选择的挂钩,您基本上只需访问前端/后端),就可以完成所有操作。

    这是一个样板:

    /**
    * Main (and only) class.
    */
    class OneTimeScript {
    
        /**
         * Plugin function hook.
         *
         * @type    string
         */
        public static $hook = \'init\';
    
    
        /**
         * Plugin function priority.
         *
         * @type    int
         */
        public static $priority = 0;
    
    
        /**
         * Run the one-time script.
         *
         * @hook    self::$hook
         * @return  void
         */
        public static function run() {
            // one-time action goes here...
    
            // clean up
            add_action(\'shutdown\', array(__CLASS__, \'unlink\'), PHP_INT_MAX);
        } // function run
    
    
        /**
         * Remove the file.
         *
         * @hook    shutdown
         * @return  void
         */
        public static function unlink() {
            unlink(__FILE__);
        } // function unlink
    
    } // class OneTimeScript
    
    add_action(OneTimeScript::$hook, array(\'OneTimeScript\', \'run\'), OneTimeScript::$priority);
    
    没有评论和东西,它看起来就像这样:

    class OneTimeScript {
        public static $hook = \'init\';
        public static $priority = 0;
    
        public static function run() {
            // one-time action goes here...
            add_action(\'shutdown\', array(__CLASS__, \'unlink\'), PHP_INT_MAX);
        } // function run
    
        public static function unlink() {
            unlink(__FILE__);
        } // function unlink
    } // class OneTimeScript
    add_action(OneTimeScript::$hook, array(\'OneTimeScript\', \'run\'), OneTimeScript::$priority);
    

    SO网友:Amit Sukapure

    当然可以,只需创建一次性代码作为插件即可。

    add_action(\'admin_init\', \'one_time_call\');
    function one_time_call()
    {
        /* YOUR SCRIPTS */
        deactivate_plugins(\'onetime/index.php\'); //deactivate current plugin
    }
    
    问题:如何在不单击激活链接的情况下激活此插件?

    只需添加activate_plugins(\'onetime/index.php\'); 在里面functions.php

    orUse必须使用插件,http://codex.wordpress.org/Must_Use_Plugins

    尝试不同的操作,就像你想执行一次性插件一样,

    admin\\u init-在admin init之后

    初始化-wordpress初始化

    加载wordpress时

    SO网友:gmazzap

    有时我会使用一个与插件停用挂钩的函数。

    请参见此处Update Old Links To Pretty Permalinks Custom Post Type

    一旦只有管理员可以激活插件,就会有一个功能检查作为副作用。

    一旦停用,无需删除文件,wordress将不会包含该文件。在上瘾中,如果你想再次跑步,你可以。再次激活和停用。

    有时我会使用像“fischi answer”中那样的瞬态。E、 g.这里query to create woocommerce products from images 或者在这里Delete/replace img tags in post content for auto published posts

    两者的结合可以是一种选择。

    SO网友:Mauro Mascia

    另一种方法是在工作完成时设置一个全局wp\\u选项,并在每次执行init hook时检查该选项。

    function my_one_time_function() {
        // Exit if the work has already been done.
        if ( get_option( \'my_one_time_function\', \'0\' ) == \'1\' ) {
            return;
        }
    
        /***** DO YOUR ONE TIME WORK *****/
    
        // Add or update the wp_option
        update_option( \'my_one_time_function\', \'1\' );
    }
    add_action( \'init\', \'my_one_time_function\' );
    
    当然,您不需要永远拥有这段代码(即使它只是从数据库中简单读取),因此您可能可以在工作完成后删除代码。如果需要重新执行代码,也可以手动将此选项值更改为0。

    SO网友:Sid

    在这一点上,我的方法有点不同。我喜欢在我的主题函数中添加我的一次性脚本作为函数。php并在特定的GET查询上运行它。

    if ( isset($_GET[\'linkupdate\']) ) {
        add_action(\'init\', \'link_update\', 10);
    }
    function link_update() {
      // One Time Script
       die;
    }
    
    要运行此操作,只需访问URL“www.sitename.com/?linkupdate”

    到目前为止,这对我来说还不错。。。

    这种方法有什么缺点吗?只是想知道。。。

    SO网友:bbruman

    我只使用一个自定义产品模板页面,我没有使用该页面,也没有连接到公共服务器上的任何内容。

    例如,如果我有一个不是活动的推荐页面(在草稿模式或其他模式下),但连接到一个页面模板single-testimonial.php - 我可以在那里放置函数,通过preview 功能或任何东西只启动一次。在调试时,对函数进行修改也很容易。

    非常简单,我更喜欢它而不是使用init 因为我可以更好地控制它何时以及如何启动。这正是我的喜好。

    SO网友:Adam Moss

    为了以防万一,我这样做了,效果很好:

    add_action( \'init\', \'upsubscriptions_setup\');
    
    function upsubscriptions_setup()
    {
        $version = get_option(\'upsubscriptions_setup_version\');
    
        // If no version is recorded yet in the DB
        if (!$version) {
            add_option(\'upsubscriptions_setup_version\', \'0.1\');
            $version = get_option(\'upsubscriptions_setup_version\');
        }
    
        if (version_compare($version, "0.1") <= 0) {
            // do stuff
            update_option(\'upsubscriptions_setup_version\', \'0.2\');
        }
    
        if (version_compare($version, "0.2") <= 0) {
            // do stuff
            update_option(\'upsubscriptions_setup_version\', \'0.3\');
        }
    
        if (version_compare($version, "0.3") <= 0) {
            // do stuff
            update_option(\'upsubscriptions_setup_version\', \'0.4\');
        }
    
        // etc
    }
    

    SO网友:pjv

    使用wp-cli eval-file 太棒了。您甚至可以在远程系统上执行此操作(using an ‘@‘ ssh alias) 使用本地脚本。

    如果你有你的代码one-time.php 在wordpress基本目录中,并且您在要运行的系统上有一个命令行,您可以执行以下操作:

    wp eval-file one-time.php
    
    如果你有文件one-time.php 在本地,您希望使用@在远程wordpress上运行它,如下所示:

    wp @remote eval-file - < one-time.php
    

    结束

    相关推荐

    Dynamic wp_enqueue_scripts?

    是否可以动态调用wp\\u enqueue\\u脚本?例如,我想在函数中使用。php我自己的函数addThemeJS( true, \'modernizr\', THEME_JS_DIR . \"/plugins/modernizr.custom.js\", array(), false, false ); addThemeJS( true, \'somthing-else\', THEME_JS_DIR . \"/plugins/somthing-else.js\", array(), fals