일회성 스크립트를 실행하는 가장 좋은 방법은 무엇입니까?


32

문제

우리 모두는 이와 같은 상황에 처해 있으며이 사이트에 대한 많은 질문에는 이와 같은 솔루션이 필요합니다. 데이터베이스를 업데이트하거나, 많은 데이터를 자동으로 삽입 meta_keys하거나 , 변환하는 등의 작업을 수행해야합니다.

물론 모범 사례를 기반으로 실행중인 시스템에서는 이런 일이 발생하지 않아야합니다.

그러나 그것이 그렇듯이, 나는이 문제에 대한 당신의 개인적인 해결책과 당신이 왜 당신을 선택했는지 듣고 싶습니다.

질문

(실행중인) WordPress 설치에서 일회성 스크립트를 어떻게 구현합니까?

여기서 문제는 주로 다음과 같은 이유 때문입니다.

  • 데이터를 삽입하는 스크립트는 두 번 이상 실행되지 않아야합니다
  • 많은 리소스가 필요한 스크립트는 모니터링 할 수없는 시점에 실행해서는 안됩니다
  • 우연히 실행해서는 안됩니다

내가 묻는 이유

나는 내 자신의 실천을 얻었고, 그것을 답변에 게시 할 것입니다. 그것이 최선의 해결책인지는 알지 못하므로 귀하의 것에 대해 알고 싶습니다. 또한 이것은 다른 질문과 관련하여 많은 시간을 요구하는 질문이며 아이디어를 수집하는 자원을 갖는 것이 좋습니다.

당신에게서 배우기를 기대합니다 :)


2
그것이 진정한 일회성 거래라면 스크립트를 작성하고 실행 한 다음 삭제합니다. 그 후에는 아무도 다시 실행할 수 없습니다. 다른 모든 것들과 마찬가지로, 코드는 도망칩니다. ;)
Otto

1
우연의 일치로 스크립트가 두 번째로 호출 될까 걱정됩니다. )하지만 난 당신의 접근 방식 수없이 한
fischi

플러그인의 관리자 페이지에서 실행하면 항상 나를 위해 일했습니다. 필요한 경우 페이지 상단에 인증 확인을 추가 할 수 있습니다.
Andrew Bartel

그러나 당신은 예정된 일회성 실행 에 대해 이야기하지 않고 수동 만 ?
birgire

1
예, wp-cron예정된 이벤트가 아닌 마이그레이션 스크립트와 같은 수동 정시 작업에 대해서만 이야기하고 있습니다 .
fischi

답변:


17

나 자신을 위해 다음을 조합하여 사용합니다.

  • 일회성 스크립트 전용 파일
  • 일시적으로 스크립트를 실수로 두 번 이상 실행하지 못하도록 중지
  • 기능 관리 또는 사용자 제어를 사용하여 스크립트를 직접 실행합니다.

구조

onetime.phpinclude-folder에 파일 ( )을 사용하는데,이 파일 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.
}

확인 후 바로 과도를 설정하는 이유 는 스크립트가 두 번 사용되는 것을 막은 후에 함수가 실행되기를 원하기 때문 입니다.

함수에서 출력이 필요한 경우 바닥 글에 주석으로 출력하거나 때로는 내용을 필터링하기도합니다.

잠금 시간은 10 분으로 설정되어 있지만 필요에 따라 조정할 수 있습니다.

대청소

내 스크립트의 성공적인 실행 후 나는 삭제 include로부터를 functions.php하고 제거 onetime.php서버에서. 과도 시간 초과를 사용했기 때문에 데이터베이스를 정리할 필요는 없지만 파일을 제거한 후 과도를 삭제할 수도 있습니다.


나는 이것에 대한 답변을 추가하려고 생각했지만이 답변의 맨 위에있는 목록을 읽은 후에는 더 이상 내 접근 방식이 거의 동일하게 보이지 않기 때문에 더 이상하지 않습니다. 따라서 +1-이것에 대한 자세한 생각도 있습니다.
tfrommen

14

당신은 또한 이것을 할 수 있습니다 :

실행 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

7

이를 위해 명령 줄 Phing 스크립트를 만들었습니다. 외부 스크립트를로드하여 실행하는 것 외에는 특별한 것이 없습니다. CLI를 통해 사용한 이유는 다음과 같습니다.

  • 실수로로드하고 싶지 않습니다 (명령을 입력해야 함)
  • 웹 루트 외부에서 실행될 수 있기 때문에 안전합니다. 다시 말해 WP에 영향을 줄 수 있지만 WP는 어떤 방식 으로든 스크립트에 도달 할 수 없습니다.
  • WP 또는 DB 자체에는 코드를 추가하지 않습니다.

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

따라서 Phing 또는 PHP CLI를 사용하여 밤에 잠을 잘 수 있습니다. WP-CLI는 웹 루트 외부에서 사용할 수 있는지 잊어 버리는 좋은 대안입니다.

이것은 인기있는 게시물이므로 여기에 스크립트의 예가 있습니다 : https://github.com/wycks/WordPhing (run.php)


이것은 좋고 간단하고 안전 해 보입니다. 또한 명령 줄을 사용하여 내 주요 관심사 중 하나 (실수로 두 번 실행되는)를 상당히 확장했습니다. 좋은 생각!
fischi

5

일회성 스크립트를 실행하는 또 다른 매우 간단한 방법은 MU 플러그인을 사용하여 수행하는 것입니다.

one-time.phpMU 플러그인 폴더에 업로드하는 일부 PHP 파일 (예 :)에 코드 를 넣고 (기본적으로 /wp-content/mu-plugins) 파일 권한을 조정하고 플러그인을 실행합니다 (예 : 선택한 후크에 따라 기본적으로 프론트 엔드를 방문하면됩니다) / backend)하고 완료했습니다.

상용구는 다음과 같습니다.

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

4

이상적인 조건에서 서버에 ssh하고 wp-cli를 사용하여 직접 기능을 실행했습니다.

이것은 종종 가능하지 않으므로 $ _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

완료되면 후크를 비활성화하십시오.


4

때로는 플러그인 비활성화에 연결된 함수를 사용했습니다.

여기를 참조하십시오 예쁜 링크로 이전 링크 업데이트 사용자 정의 게시물 유형

관리자 만 플러그인을 활성화 할 수있게되면 기능 검사가 부작용으로 발생합니다.

일단 비활성화되면 파일을 삭제할 필요가 없습니다. wordress에 포함되지 않습니다. 중독에서 다시 달리고 싶다면 할 수 있습니다. 다시 활성화 및 비활성화

때로는 @fischi 답변과 같은 과도기를 사용했습니다. 예 : 이미지에서 우 커머스 제품을 만들 거나 여기 에 자동 게시 게시물의 게시물 콘텐츠에서 img 태그를 삭제 / 대체 하려면 여기를 쿼리 하십시오.

둘의 조합이 대안이 될 수 있습니다.


이것은 또한 좋은 아이디어입니다. 다시 비활성화하기 위해 항상 활성화 해야하는 성가신 경우 동일한 기능을 플러그인 활성화에 연결할 수도 있습니다.
fischi

예, 원한다면 그러나 클릭 한 번으로 스크립트를 한 번만 실행해도 큰 노력이 아니라고 생각합니다. CLI 명령 또는 파일 처리 (이름 바꾸기, 삭제)와 관련된 다른 솔루션에는 더 많은 "작업"이 필요합니다. 또한 후크에 의존 할 때마다 전역 변수에 의존하여 코드의 보안 / 예측 가능성과 관련된 잠재적 인 문제를 추가로 추가합니다. @fischi
gmazzap

나는 두 번의 클릭이 너무 많다고 생각하지 않고 그냥 물어보고 싶었다 :)
fischi

3

확실히 할 수 있습니다. 플러그인으로 일회용 코드를 만드십시오.

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

일회성 플러그인을 실행하려고 할 때와 다른 작업을 시도하십시오.

  1. admin_init-관리자 초기화 후

  2. init-워드 프레스 init

  3. wp-워드 프레스가로드 될 때


2

다른 방법은 작업이 완료 될 때 전역 wp_option을 설정하고 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으로 수동으로 변경할 수 있습니다.


1

내 접근 방식은 이것과 약간 다릅니다. 테마의 function.php에 함수로 일회성 스크립트를 추가하고 특정 GET 쿼리에서 실행하고 싶습니다.

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

이를 실행하려면 URL "www.sitename.com/?linkupdate"를 방문하십시오.

이것은 지금까지 잘 작동합니다 ...

이 방법에는 단점이 있습니까? 궁금해 ...


1

사용하지 않고 공용 서버의 항목에 연결되어 있지 않은 단일 사용자 지정 제품 템플릿 페이지 만 사용합니다.

예를 들어, 초안 모드 또는 기타 상태로 존재하지만 단일 페이지 템플릿에 연결된 평가 페이지가있는 경우처럼 single-testimonial.php-거기에 함수를 배치 preview하고 a 및 함수 를 통해 페이지를로드 할 수 있습니다. 한 번 발사했다. 디버깅시 함수를 수정하는 것도 매우 쉽습니다.

실제로 init시작하는 시점과 방법을 더 잘 제어 할 수 있기 때문에 사용 하기보다 선호하기 쉽습니다 . 단지 내 취향.


0

그것이 도움이되는 경우, 이것이 내가 한 일이며 잘 작동합니다.

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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.