我们所有人都处在这样的情况下,这个站点上的许多问题都需要这样的解决方案。您要么必须更新数据库,自动插入大量数据,要么转换
meta_keys
或类似的方法。当然,在基于最佳实践的运行系统中,这应该不会发生。
但是这样做的话,我很想听听您对这个问题的个人解决方案,以及您为什么选择您的解决方案。
问题
您如何实现一个您的(正在运行的)WordPress安装中是否存在时间脚本?
这里的问题主要是由于以下原因:
插入数据的脚本不应再运行不止一次
需要大量资源的脚本不应在无法监视的时候运行
它们不应偶然运行
我问的原因
我有自己的见习方法,我将其发布在答案中。我不知道这是否是最好的解决方案,所以我想了解您的解决方案。另外,这是一个在其他问题中经常问到的问题,拥有一个收集想法的资源非常有用。
,希望向您学习:)
#1 楼
我自己使用以下组合:一个专用于一次性脚本的文件
使用瞬态阻止脚本意外运行超过一次
使用功能管理或用户控制来确保脚本仅由我运行。
结构
我在包含文件夹
onetime.php
中使用了一个文件(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.
}
我检查瞬态是否存在后立即设置瞬态的原因是,我希望函数在脚本被锁定后不被蜂鸣两次使用后才能执行。 br />
如果我需要函数的任何输出,我可以将其打印为页脚中的注释,有时甚至过滤内容。
锁定时间设置为10分钟,但可以根据您的需要进行调整。
清理
执行成功后我的脚本使用我从
include
删除functions.php
,并从服务器中删除onetime.php
。当我为过渡使用超时时,我不需要清理数据库,但是当然您也可以在删除文件后删除过渡。评论
我本来打算添加我的答案,但是在阅读完该答案顶部的清单之后,我将不再...我的方法几乎完全相同。因此+1-对此也有详细的想法。
–tfrommen
2014-2-5 20:58
#2 楼
您还可以执行以下操作:运行
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');
}
评论
这就是我们要做的;它几乎可以保证是万无一失的。
– Qix-蒙尼卡(MS)被盗
2015年1月6日在21:07
太好了,我不知道为什么这个主意没想到,谢谢:)
– Shahin
20-2-11在7:01
#3 楼
我为此创建了一个命令行Phing脚本,除了加载要运行的外部脚本外,没有什么特别的。我通过CLI使用它的原因是:我不希望它被错误加载(需要键入命令)
它很安全,因为它可以在Web根目录之外运行,换句话说,它可以影响WP,但是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。 com / wycks / WordPhing(run.php)
评论
这看起来很简单,很安全。您还通过使用命令行涵盖了我的主要关切之一(我偶然执行了两次)。好主意!
– fischi
2014年2月6日在7:18
#4 楼
在理想条件下,我会使用服务器ssh进入服务器并自己执行该函数。这通常是不可能的,因此我倾向于设置$ _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
并在完成后禁用钩子。
#5 楼
运行一次性脚本的另一种非常简单的方法是通过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);
没有任何评论和内容,它看起来像这样:
#6 楼
有时,我使用了与插件停用相关的函数。请参见此处将旧链接更新为漂亮的永久链接自定义帖子类型
一旦只有管理员可以激活插件,就会出现功能检查的副作用。
没有必要删除文件,一旦停用,它便不会包含在wordress中。
如果您想重新运行它,可以上瘾。再次激活和停用。
有时我会像@fischi答案中那样使用瞬态。例如。在此处查询以从图像创建woocommerce产品,或在此处删除/替换自动发布的帖子的帖子内容中的img标签。
可以将两者结合使用。
评论
这也是一个非常好的主意。如果它变得烦人,总是必须再次激活才能将其停用,那么您也可以将相同的功能与该插件的激活挂钩,对吗?
– fischi
2014年2月6日在7:20
是的,如果你想。但是,我认为两次单击并不是运行一次性脚本的巨大努力。任何其他涉及CLI命令或文件处理(重新命名,删除)的解决方案都需要更多的“工作”。此外,每次依赖钩子时,都依赖于全局变量,从而增加了与代码的安全性/可预测性有关的潜在问题。 @fischi
– gmazzap♦
2014年2月6日11:00
我认为两次单击也不算太多,只是想问一下:)
– fischi
2014年2月6日,12:44
#7 楼
绝对可以,只需将您的一次性代码创建为插件即可。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
或
使用必须使用的插件http://codex.wordpress.org/Must_Use_Plugins
尝试不同的操作,就像当您要执行一次性插件,
admin_init-管理员初始化后
init-wordpress初始化
wp-加载wordpress时
#8 楼
另一种方法是在工作完成后设置全局wp_option,并在每次执行init钩子时检查该选项。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执行代码。
#9 楼
我的方法与此有所不同。我想将一次性脚本作为函数添加到主题的function.php中,并在特定的GET查询上运行它。if ( isset($_GET['linkupdate']) ) {
add_action('init', 'link_update', 10);
}
function link_update() {
// One Time Script
die;
}
要运行此脚本,只需访问网址“ www.sitename.com/?linkupdate”
到目前为止,这对我来说仍然很好...
这种方法是否有任何缺点?只是想知道...
#10 楼
我只使用了一个未使用的自定义产品模板页面,并且未连接到公共服务器上的任何内容。如果我有一个不在使用中的推荐页面(在草稿模式下) (或其他),但连接到单个页面模板,例如
single-testimonial.php
-我可以在其中放置函数,通过preview
加载页面,然后函数或任何函数启动一次。在调试的情况下对功能进行修改也非常容易。确实很容易,并且我更喜欢使用
init
,因为我可以更好地控制其启动时间和方式。只是我的喜好。#11 楼
以防万一,这就是我所做的并且效果很好: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
}
#12 楼
使用wp-clieval-file
很棒。您甚至可以在具有本地脚本的远程系统(使用'@'ssh别名)上进行操作。如果您在wordpress基本目录中的
one-time.php
中有您的代码,并且您想要的系统上有命令行可以执行以下操作:wp eval-file one-time.php
如果本地具有文件
one-time.php
,并且您想使用@在远程wordpress上运行它,则如下所示:wp @remote eval-file - < one-time.php
评论
如果这确实是一次性交易,那么我编写脚本,运行它,然后删除它。此后没有人不能再次运行它。像所有事物一样,代码瞬息万变。 ;)我担心的是,每次碰巧都可能再次调用脚本。但我无数次地采用了您的方法;)
在插件的管理页面上运行它,始终对我有用。您可以在页面顶部添加身份验证检查,以确保在必要时使用身份验证。
但是您不是在谈论计划的一次执行,而是手动操作?
是的,我只是在谈论手动准时操作,例如迁移脚本等,而不是wp-cron计划的事件。