it-swarm-vi.tech

Thực hành tốt nhất của bạn để thực hiện các kịch bản một lần là gì?

Vấn đề

Tất cả chúng ta đã ở trong một tình huống như thế này, và rất nhiều câu hỏi trên trang web này cần một giải pháp như thế này. Bạn có thể phải cập nhật cơ sở dữ liệu, tự động chèn nhiều dữ liệu, chuyển đổi meta_keys hoặc một cái gì đó tương tự.

Tất nhiên, trong một hệ thống đang chạy dựa trên các thực tiễn tốt nhất, điều này không nên xảy ra.

Nhưng như nó, tôi rất thích nghe giải pháp cá nhân của bạn cho vấn đề này, và tại sao bạn chọn giải pháp của bạn.

Câu hỏi

Làm thế nào để bạn thực hiện các tập lệnh một lần trong cài đặt WordPress (đang chạy) của bạn?

Vấn đề ở đây chủ yếu là vì những lý do sau:

  • Các tập lệnh chèn dữ liệu không nên chạy nhiều hơn một lần
  • Các tập lệnh yêu cầu nhiều nguồn tài nguyên không nên chạy vào thời điểm mà chúng không thể được giám sát
  • Họ không nên chạy một cách tình cờ

Lý do tôi hỏi

Tôi đã có thực hành của riêng tôi, tôi sẽ đăng nó trong câu trả lời. Vì tôi không biết đó có phải là giải pháp tốt nhất ngoài kia không, tôi muốn biết về bạn. Ngoài ra, đây là một câu hỏi được hỏi rất nhiều lần trong bối cảnh của các câu hỏi khác, và sẽ thật tuyệt khi có một nguồn tài nguyên thu thập các ý tưởng.

mong được học hỏi từ bạn :)

31
fischi

Tôi tự mình sử dụng kết hợp:

  • một tệp dành riêng cho tập lệnh một lần
  • sử dụng tạm thời để ngăn tập lệnh vô tình chạy nhiều lần
  • sử dụng quản lý khả năng hoặc kiểm soát người dùng để đảm bảo tập lệnh được điều hành bởi tôi.

Kết cấu

Tôi sử dụng một tệp (onetime.php) trong thư mục bao gồm inc, được bao gồm trong functions.php và bị xóa từ đó sau khi sử dụng.

include( 'inc/onetime.php' );

Các tập tin cho chính kịch bản

Trong onetime.php, chức năng của tôi f711_my_onetime_function() được đặt. Vì nó có thể là bất kỳ chức năng. Tôi giả sử kịch bản của bạn được kiểm tra và hoạt động chính xác.

Để đạt được sự kiểm soát đối với việc thực thi tập lệnh, tôi sử dụng cả hai

Kiểm soát khả năng

Để ngăn người dùng khác vô tình thực thi tập lệnh của tôi:

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

hoặc là

if ( get_current_user_id() == 711 ) // check if it is me - I prefer restricting the execution to me, not to all admins.

thoáng qua

để ngăn mình khỏi việc vô tình thực thi kịch bản nhiều lần.

$transient = 'f711_my_onetime_check';
if ( !get_transient( $transient ) ) // check if the function was not executed.

Tệp để thực thi tập lệnh trong chức năng của tôi f711_my_onetime_function() sẽ trông như thế:

$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.
}

Lý do tôi đặt tạm thời ngay sau khi kiểm tra nếu nó tồn tại là vì tôi muốn chức năng được thực thi sau tập lệnh đã bị khóa khi sử dụng hai lần.

Nếu tôi cần bất kỳ đầu ra nào từ chức năng của mình, tôi sẽ in nó ra dưới dạng một nhận xét ở chân trang hoặc đôi khi tôi thậm chí còn lọc nội dung.

Thời gian khóa được đặt thành 10 phút, nhưng có thể được điều chỉnh theo nhu cầu của bạn.

Dọn dẹp

Sau khi thực hiện thành công tập lệnh của mình, tôi xóa include khỏi functions.php và xóa onetime.php khỏi máy chủ. Khi tôi sử dụng thời gian chờ tạm thời, tôi không cần phải xóa cơ sở dữ liệu, nhưng tất nhiên bạn cũng có thể xóa tạm thời sau khi bạn xóa tệp.

16
fischi

Bạn cũng có thể làm điều này:

chạy onetime.php và đổi tên nó sau khi thực hiện.

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');
}
13
Ravinder Kumar

Tôi đã tạo một tập lệnh Phing script cho việc này, nó không có gì đặc biệt ngoài việc tải một tập lệnh bên ngoài để chạy. Lý do tôi sử dụng nó thông qua CLI là vì:

  • Tôi không muốn nó tải nhầm (cần phải gõ lệnh)
  • Nó an toàn vì nó có thể chạy bên ngoài web root, nói cách khác, nó có thể ảnh hưởng WP nhưng WP không thể tiếp cận tập lệnh theo bất kỳ cách nào.
  • Nó không thêm bất kỳ mã nào vào WP hoặc chính DB.

require('..path to ../wp-blog-header.php');
//bunch of WP globals
define('WP_USE_THEMES', false);
//custom code

Vì vậy, bạn có thể sử dụng Phing hoặc PHP CLI và ngủ vào ban đêm. WP-CLI cũng là một lựa chọn tốt mặc dù tôi quên nếu bạn có thể sử dụng nó bên ngoài web root.

Vì đây là một bài đăng phổ biến ở đây là một ví dụ về tập lệnh: https://github.com/wycks/WordPhing (run.php)

7
Wyck

Một cách khá đơn giản khác để chạy tập lệnh một lần là thực hiện việc này bằng plugin MU.

Đặt mã vào một số tệp PHP (ví dụ: one-time.php) mà bạn tải lên thư mục trình cắm MU của bạn (theo mặc định /wp-content/mu-plugins), điều chỉnh quyền của tệp, chạy plugin (nghĩa là theo hook bạn đã chọn, về cơ bản bạn chỉ cần truy cập vào frontend/backend), và bạn đã hoàn tất.

Đây là một cái nồi:

/**
* 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);

Không có ý kiến ​​và công cụ, nó chỉ trông như thế này:

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);
5
tfrommen

Đôi khi tôi đã sử dụng một chức năng được nối vào việc hủy kích hoạt plugin.

Xem tại đây Cập nhật các liên kết cũ thành Loại bài đăng tùy chỉnh đẹp

Khi chỉ quản trị viên mới có thể kích hoạt bổ trợ, kiểm tra khả năng là tác dụng phụ.

Không cần phải xóa tập tin một khi đã tắt nó sẽ không được bao gồm bởi wordress. Trong nghiện nếu bạn muốn chạy lại nó có thể. Kích hoạt và hủy kích hoạt lại.

Và đôi khi tôi đã sử dụng tạm thời được sử dụng như trong câu trả lời @fischi. Ví dụ. tại đây truy vấn để tạo các sản phẩm thương mại điện tử từ hình ảnh hoặc tại đây Xóa/thay thế thẻ img trong nội dung bài đăng cho các bài đăng được xuất bản tự động

Một sự kết hợp của cả hai có thể là một sự thay thế.

4
gmazzap

Chắc chắn bạn có thể, Chỉ cần tạo mã một lần của bạn dưới dạng plugin.

add_action('admin_init', 'one_time_call');
function one_time_call()
{
    /* YOUR SCRIPTS */
    deactivate_plugins('onetime/index.php'); //deactivate current plugin
}

Vấn đề làm thế nào để tôi kích hoạt plugin này mà không cần nhấp vào Kích hoạt liên kết?

chỉ cần thêm activate_plugins('onetime/index.php'); trong functions.php

hoặc Sử dụng phải sử dụng plugin, http://codex.wordpress.org/Must_Use_Plugins

Hãy thử với các hành động khác nhau như khi bạn muốn thực thi plugin một lần,

  1. admin_init - sau khi quản trị init

  2. init - initpress

  3. wp - khi tải wordpress

3
Amit Sukapure

Trong điều kiện lý tưởng, tôi sẽ ssh vào máy chủ và tự thực hiện chức năng bằng wp-cli.

Tuy nhiên, điều này thường không thể thực hiện được, vì vậy tôi có xu hướng đặt biến $ _GET và móc nó vào 'init', ví dụ:

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

sau đó đánh

http://my_blog.com/?one_time=an_unlikely_string

và vô hiệu hóa móc khi hoàn thành.

3
djb

Một cách khác là đặt wp_option toàn cầu khi công việc được hoàn thành và kiểm tra tùy chọn đó mỗi khi hook hook được thực thi.

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' );

Đương nhiên, bạn không cần phải có mã này mãi mãi (ngay cả khi nó chỉ đơn giản là đọc từ cơ sở dữ liệu), vì vậy bạn có thể xóa mã khi công việc được hoàn thành. Ngoài ra, bạn có thể tự thay đổi giá trị tùy chọn này thành 0 nếu bạn cần thực hiện lại mã.

2
Mauro Mascia

Tôi chỉ sử dụng một trang mẫu sản phẩm tùy chỉnh duy nhất mà tôi không sử dụng và không được kết nối với bất kỳ thứ gì trên máy chủ công cộng.

Giống như nếu tôi có một trang chứng thực không tồn tại (ở chế độ nháp hoặc bất cứ thứ gì), nhưng được kết nối với một mẫu trang duy nhất, ví dụ single-testimonial.php - Tôi có thể đặt các chức năng trong đó, tải trang qua preview và chức năng hoặc bất cứ điều gì được đưa ra một lần. Cũng rất dễ dàng để sửa đổi chức năng trong trường hợp gỡ lỗi.

Thực sự dễ dàng và tôi thích nó hơn là sử dụng init vì tôi có nhiều quyền kiểm soát hơn khi nào và cách thức ra mắt. Chỉ là sở thích của tôi.

1
bbruman

Cách tiếp cận của tôi là một chút khác nhau về điều này. Tôi muốn thêm tập lệnh một lần của mình dưới dạng hàm trong hàm.php của chủ đề và chạy nó trên một truy vấn GET cụ thể.

if ( isset($_GET['linkupdate']) ) {
    add_action('init', 'link_update', 10);
}
function link_update() {
  // One Time Script
   die;
}

Để chạy cái này, chỉ cần truy cập URL "www.sitename.com/?linkupdate"

Điều này đang làm việc tốt cho tôi cho đến bây giờ ...

Phương pháp này có bất kỳ nhược điểm? Chỉ tự hỏi ...

1
Sid

Chỉ trong trường hợp nó giúp, đây là những gì tôi đã làm và nó hoạt động tốt:

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
}
0
Adam Moss