Cara Melewati Variabel Eksternal ke Filter / Tindakan


11

Saya menemukan diri saya perlu meneruskan data khusus ke filter yang disediakan oleh plugin pihak ke-3. Semua cara yang kulihat untuk melakukan ini benar-benar rumit dan sulit untuk membungkus kepalaku.

Ambil contoh ini:

$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Bagaimana saya bisa meneruskan $scorevariabel ke add_score_to_title()?

Apa yang akhirnya saya lakukan adalah menambahkan variabel saya ke $wpobjek global . Jadi Anda berakhir dengan ini:

global $wp;
$score = 42; //Some crazy calculation I don't want to repeat.
$wp->some_random_name_for_score = $score;

function add_score_to_title($title) {
    global $wp;
    $score = $wp->some_random_name_for_score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');

Kotor? Mungkin. Sederhana? Ya! Adakah kelemahan teknik ini? Tolong diskusikan.

PEMBARUAN Berikut adalah kode lengkap yang dimaksud -> http://pastebin.com/fkSXY04m


Cukup lakukan "perhitungan gila" Anda di dalam fungsi itu ...
onetrickpony

Mungkin sulit dimengerti dari contoh sederhana saya. Variabel $ skor digunakan di seluruh templat itu. Saya ingin menghitungnya sekali dan meneruskan nilai itu ke fungsi yang merupakan panggilan balik untuk filter untuk mengubah judul halaman. Filter ini digunakan dalam Paket SEO All In One. Menjalankan perhitungan berkali-kali tidak diinginkan.
kingkool68

Maka Anda harus memposting lebih banyak kode jika Anda ingin mendapatkan solusi yang tidak melibatkan memperkenalkan negara global (yang seharusnya tidak pernah diperlukan).
onetrickpony

Berikut adalah kode lengkap dalam file templat. $scoredihitung dengan mengulangi berbagai hal dan menambah variabel. pastebin.com/fkSXY04m
kingkool68

Jawaban:


10

Anda memiliki setidaknya dua opsi:

  1. Globalisasi variabel yang diinginkan, dan kemudian rujuk di dalam callback
  2. Bungkus logika perhitungan skor dengan fungsi, lalu rujuk di dalam panggilan balik

Globalisasi Variabelnya

<?php
global $score;
$score = 42; //Some crazy calculation I don't want to repeat.

function add_score_to_title($title) {
    global $score;
    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Bungkus Perhitungan Skor

Jika Anda hanya membutuhkan perhitungan skor di dalam filter, tarik logika ke dalam callback itu sendiri:

<?php
function add_score_to_title($title) {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
        $order = $question->order;

        if( $order >= 100 ) {
            break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Lebih baik lagi, Anda bisa membungkus perhitungan skor Anda dalam fungsi sendiri, dan kemudian memanggil fungsi itu di dalam panggilan balik Anda:

<?php
function wpse48677_get_score() {
    $score = 0;
    $questions = get_quiz_result_questions();
    $total_questions = 0;
    foreach( $questions as $question ) {
    $order = $question->order;

    if( $order >= 100 ) {
        break;
    }

    if( $question->correct == $_POST['Q'][$order] ) {
        $score++;
    }
    $total_questions++;
    $output['score'] = $score;
    $output['total_questions'] = $total_questions;

    return $output;
}

function add_score_to_title($title) {

    $score_results = wpse48677_get_score();

    $score = $score_results['score'];

    return 'Quiz Results (' . $score . '/') - ' . $title;
}

add_filter( 'aioseop_title_single', 'add_score_to_title');
?>

Jika Anda menemukan masalah dalam referensi $_POSTobjek, Anda juga dapat mendaftarkan variabel kueri Anda dan kemudian menggunakan secara get_query_var()internal untuk mendapatkan data:

function add_score_query_vars( $query_vars ) {
    $query_vars[] = 'Q';

    return $query_vars;
}
add_filter( 'query_vars', 'add_score_query_vars' );

Dengan ini di tempat, $_POST['Q']bisa diganti dengan get_query_var('Q').


Ini tidak ada hubungannya dengan jumlah argumen yang diteruskan ke fungsi oleh apply_filters ...
onetrickpony

Mencoba metode # 1 yang Anda sebutkan tentang mengglobalisasi variabel. Itu tidak bekerja. Parameter args yang diterima juga tidak membantu saya karena saya tidak memiliki kendali atas variabel apa yang dilewatkan ke fungsi callback.
kingkool68

Maaf kamu benar. Saya menghitung $scoredulu dan kemudian mengglobalkannya. Tidak heran itu tidak berhasil. Terima kasih!
kingkool68

-1. Opsi pertama memperlihatkan variabel dalam keadaan global, opsi 2 tidak berfungsi ...
onetrickpony

1
" Global itu jahat "? Benarkah ? Maka seluruh kode WordPress sebaiknya ditulis, karena bergantung pada beberapa variabel global .
Chip Bennett

3
function add_score_to_title($title = false) {
  static $score = false;

  if($score === false){
    // do calc
  }

  // plugin call (filter)   
  if($title !== false)
    return 'Quiz Results (' . $score . ') - ' . $title;

  // your call
  return $score;
}

Panggil fungsi di mana saja dalam skrip Anda untuk mendapatkan skor, itu hanya akan dihitung sekali.

Cara lain, menggunakan fungsi anonim :

// do the calc
$score = 'xxx';

add_filter('aioseop_title_single', function($title) use($score){
  return 'Quiz Results (' . $score . ') - ' . $title;  
});

3
Fungsi anonim tidak boleh digunakan add_filter()atau add_action()dipanggil. Mereka tidak dapat dihapus melalui remove_function().
Chip Bennett

Maksud Anda remove_filter, yang terutama digunakan untuk menghapus filter
bawaan

1
Iya; maaf: remove_filter()dan remove_action(). Dan tidak ada alasan filter Plugin / Tema tidak dapat dihilangkan secara wajar: timpa enqueues Plugin, Tema Anak, dll.
Chip Bennett

0

Contoh berikut melihat variabel $my_calculationdalam lingkup global, namun dari dalam fungsi lokal kami, kami perlu mendeklarasikan global $my_calculationuntuk mengakses variabel dalam lingkup global.

<?php 

    $my_calculation = 'result!';

    function my_function() {

        global $my_calculation;
        return $my_calculation;

    }

    add_filter( 'function_something_here', 'my_function');   

?>

Ini hanya salah satu cara untuk melakukannya dan tampaknya rapi. Apakah ini akan berhasil untuk Anda?


Bagaimana ini berbeda dari yang sudah dia miliki?
onetrickpony

Sekali lagi deklarasi "global". Lihatlah contoh keduanya, dia menyatakan $ $ dua kali gloabl!
Adam

Itu juga tidak bekerja. Ini adalah hal pertama yang saya coba.
kingkool68

Apakah Anda dapat printatau echohasil Anda untuk memastikan bahwa fungsi Anda memang berfungsi sebelum meneruskannya ke filter?
Adam

Ups! Globalisasi $scorememang berhasil. Saya melakukan kesalahan dan menetapkan $scorepertama kemudian mengglobal yang jelas tidak berhasil. Melakukannya dengan cara yang benar dengan mengglobalisasi $scoreterlebih dahulu kemudian memberikannya nilai berhasil seperti yang diharapkan. Terima kasih semuanya.
kingkool68
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.