एक बार की स्क्रिप्ट निष्पादित करने के लिए आपका सबसे अच्छा अभ्यास क्या है?


32

समस्या

हम सभी इस तरह की स्थिति में हैं, और इस साइट पर बहुत सारे प्रश्नों को इस तरह के समाधान की आवश्यकता है। आपको या तो एक डेटाबेस को अपडेट करना है, बहुत सारे डेटा को स्वचालित रूप से सम्मिलित करें, कन्वर्ट करें meta_keys, या कुछ इसी तरह।

बेशक, सर्वोत्तम प्रथाओं पर आधारित एक रनिंग सिस्टम में ऐसा नहीं होना चाहिए।

लेकिन जैसा कि यह होता है, मैं इस समस्या का आपका व्यक्तिगत समाधान सुनना पसंद करूंगा, और आपने इसे क्यों चुना।

प्रश्न

आप अपने (चल रहे) वर्डप्रेस इंस्टॉल में एकमुश्त स्क्रिप्ट कैसे लागू करते हैं?

यहाँ समस्या मुख्य रूप से निम्नलिखित कारणों से है:

  • यह बताता है कि डेटा सम्मिलित करने के लिए एक से अधिक बार नहीं चलना चाहिए
  • ऐसे लिपियों की आवश्यकता होती है, जिन्हें किसी ऐसे समय में नहीं चलाया जाना चाहिए जब उनकी निगरानी नहीं की जा सकती है
  • उन्हें दुर्घटना से नहीं चलाना चाहिए

कारण मैं पूछता हूं

मुझे अपना अभ्यास मिल गया है, मैं इसे उत्तर में पोस्ट करने जा रहा हूं। जैसा कि मुझे नहीं पता कि यह वहां से सबसे अच्छा समाधान है, मैं आपके बारे में जानना चाहूंगा। साथ ही, यह एक ऐसा प्रश्न है जो अन्य प्रश्नों के संदर्भ में बहुत बार पूछा जाता है, और यह एक महान स्रोत होगा जिसमें विचारों को एकत्र करना होगा।

आप से सीखने के लिए तत्पर :)


2
अगर यह वास्तव में एक बार ही सौदा होता है, तो मैं स्क्रिप्ट लिखता हूं, मैं इसे चलाता हूं, फिर मैं इसे हटा देता हूं। उसके बाद उसे फिर से कोई नहीं चला सकता। सभी चीजों की तरह, कोड क्षणभंगुर है। ;)
ओटो

1
बात यह है कि मैं चिंतित हूं कि एक स्क्रिप्ट को दूसरी बार संयोग कहा जा सकता है। लेकिन मैंने आपका दृष्टिकोण अनगिनत बार किया;)
फिशी

इसे एक प्लगइन के व्यवस्थापक पृष्ठ पर चलाएं, हमेशा मेरे लिए काम किया। यदि आवश्यक हो तो यह सुनिश्चित करने के लिए आप पृष्ठ के शीर्ष पर स्थितीय जांच जोड़ सकते हैं।
एंड्रयू बार्टल

लेकिन आप नियत एक बार निष्पादन के बारे में बात नहीं कर रहे हैं , केवल मैनुअल ?
बीरगिरे

1
हां, मैं केवल मैनुअल ऑन-टाइम ऑपरेशन, जैसे माइग्रेटिंग-स्क्रिप्ट आदि के बारे में बात कर रहा हूं, न कि wp-cronअनुसूचित घटनाओं के बारे में।
फिशी

जवाबों:


17

मैं अपने लिए एक संयोजन का उपयोग करता हूं:

  • एक बार की स्क्रिप्ट के लिए समर्पित एक फ़ाइल
  • गलती से स्क्रिप्ट को एक से अधिक बार चलाने से रोकने के लिए एक क्षणिक का उपयोग करना
  • स्क्रिप्ट सुनिश्चित करने के लिए क्षमता-प्रबंधन या उपयोगकर्ता-नियंत्रण का उपयोग सिर्फ मेरे द्वारा चलाया जाता है।

संरचना

मैं 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.
}

कारण यह है कि मैं जाँच के तुरंत बाद क्षणिक को सेट करता हूँ यदि यह मौजूद है कि मैं चाहता हूं कि स्क्रिप्ट के दो बार इस्तेमाल होने वाले मधुमक्खी से लॉक होने के बाद फ़ंक्शन को निष्पादित किया जाए।

यदि मुझे अपने फ़ंक्शन से किसी भी आउटपुट की आवश्यकता है, तो मैं या तो इसे पाद लेख में एक टिप्पणी के रूप में प्रिंट करता हूं, या कभी-कभी मैं सामग्री को फ़िल्टर भी करता हूं।

तालाबंदी 10 मिनट के लिए सेट है, लेकिन आपकी आवश्यकताओं के लिए समायोजित किया जा सकता है।

साफ - सफाई

मेरी स्क्रिप्ट के सफल निष्पादन के बाद मेरे द्वारा हटाए जाने includeसे functions.php, और हटाने onetime.phpसर्वर से। जैसा कि मैंने क्षणिक के लिए एक टाइमआउट का उपयोग किया है, मुझे डेटाबेस को साफ करने की आवश्यकता नहीं है, लेकिन निश्चित रूप से आप फ़ाइल को हटाने के बाद आप क्षणिक को भी हटा सकते हैं।


मैंने इस बारे में अपना उत्तर जोड़ने के बारे में सोचा, लेकिन इस उत्तर के शीर्ष पर आपकी लिस्टिंग को ठीक से पढ़ने के बाद ... मैं अब ऐसा नहीं करूंगा क्योंकि मेरा दृष्टिकोण लगभग वैसा ही दिखता है। तो इसके लिए +1 - इस पर विस्तृत विचारों के लिए भी।
tfrommen 20

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

एक समय स्क्रिप्ट चलाने का एक और बहुत सरल तरीका यह है कि यह एक म्यू प्लगइन के माध्यम से किया जाए।

कुछ PHP फ़ाइल (जैसे one-time.php) में कोड डालें जिसे आप अपने एमयू प्लगइन्स फ़ोल्डर में अपलोड करते हैं (डिफ़ॉल्ट रूप से)/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);

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

कभी-कभी मैंने प्लगइन डिएक्टिवेशन पर हुक किए गए फ़ंक्शन का उपयोग किया।

यहां देखें पुराने लिंक को अपडेट करने के लिए पुराने लिंक कस्टम पोस्ट प्रकार

एक बार जब केवल प्लगइन्स को सक्रिय किया जा सकता है, तो साइड इफेक्ट के रूप में क्षमता की जांच होती है।

एक बार फाइल डिलीट करने की कोई जरूरत नहीं है, इसे वर्डप्रेस द्वारा शामिल नहीं किया जाएगा। नशे की लत में अगर आप फिर से भागना चाहते हैं तो आप कर सकते हैं। सक्रिय करना और फिर से निष्क्रिय करना।

और कभी-कभी मैंने @fischi उत्तर में उपयोग किए गए क्षणिक का उपयोग किया। उदाहरण के लिए यहाँ छवियों से woocommerce उत्पाद बनाने के लिए या ऑटो प्रकाशित पोस्ट के लिए पोस्ट सामग्री में img टैग हटाएं / बदलें

दोनों का एक संयोजन एक विकल्प हो सकता है।


यह भी एक बहुत अच्छा आइडिया है। अगर यह फिर से निष्क्रिय करने के लिए सक्रिय करने के लिए हमेशा परेशान हो जाता है, तो आप प्लगइन के सक्रियण के लिए एक ही फ़ंक्शन को हुक भी कर सकते हैं, है ना?
fischi

हा यदि आप चाहते हैं। हालाँकि, मुझे लगता है कि एक बार की स्क्रिप्ट को चलाने के लिए 2 क्लिक बहुत अच्छा प्रयास नहीं है। किसी भी अन्य समाधान जिसमें सीएलआई कमांड या फ़ाइल हैंडलिंग (नाम बदलना, हटाना) शामिल है, को अधिक "काम" की आवश्यकता है। इसके अलावा, हर बार जब आप हुक पर भरोसा करते हैं, तो आप वैश्विक चर पर भरोसा कर रहे हैं, कोड की सुरक्षा / भविष्यवाणी के संबंध में संभावित मुद्दों की एक अतिरिक्त परत जोड़ रहे हैं। @fischi
gmazzap

मुझे नहीं लगता कि दो क्लिक बहुत अधिक हैं, बस पूछना चाहता था :)
फिस्ची

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 - व्यवस्थापक init के बाद

  2. init - वर्डप्रेस init

  3. wp - जब wordpress load हुआ


2

एक अन्य तरीका यह है कि जब काम पूरा हो जाए और उस विकल्प के लिए हर बार इनिट हुक निष्पादित हो, तो एक वैश्विक wp_option सेट करें।

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;
}

इसे चलाने के लिए, बस "www.sitename.com/?linkupdate" URL पर जाएँ

यह मेरे लिए अब तक ठीक काम कर रहा है ...

क्या इस पद्धति में कोई कमियां हैं? बस सोच रहा...


1

मैं सिर्फ एक ही कस्टम उत्पाद टेम्प्लेट पृष्ठ का उपयोग करता हूं जिसका मैं उपयोग नहीं कर रहा हूं और सार्वजनिक सर्वर पर किसी भी चीज से जुड़ा नहीं हूं।

जैसे अगर मेरे पास एक प्रशंसापत्र पृष्ठ है जो लाइव नहीं है (ड्राफ्ट मोड में, या जो भी हो), लेकिन एकल पृष्ठ टेम्पलेट से जुड़ा हुआ है, उदाहरण के लिए single-testimonial.php- मैं वहां फ़ंक्शन कर सकता हूं, पृष्ठ को ए previewऔर फ़ंक्शन के माध्यम से लोड कर सकता हूं या जो भी हो एक बार लॉन्च किया गया। डिबगिंग के मामले में फ़ंक्शन में संशोधन करना भी बहुत आसान है।

वास्तव में आसान है और मैं इसका उपयोग करना पसंद करता 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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.