web-dev-qa-db-fra.com

Pourquoi ce tableau global renvoie NULL à partir d'une fonction de rappel

Cela m'a rendu fou pendant des heures maintenant ... Merci de me dire pourquoi le tableau $ ppk_fields est vide dans la fonction ppk_field_callback? Notez qu'il renvoie les valeurs correctes dans la fonction ppk_default_id mais qu'il ne s'agit pas d'une fonction de rappel. Je vous remercie!

ppk.php

class Ppk {

    public function ini() {
        add_action( 'admin_menu', array( $this, 'add_ppk_p_menu' ) );
    }

    public function add_ppk_p_menu() {
        add_submenu_page( 'tools.php', 'PPK PLUGIN', 'PPK PLUGIN', 'manage_options', 'ppk_p', array( $this, 'ppk_build_dashboard' ) );
    }

    public function ppk_build_dashboard() {
        require_once plugin_dir_path( __FILE__ ) . 'ppk-builder.php';
    }

}

if ( class_exists( 'Ppk' ) ) {
    $ppk = new Ppk();
    $ppk->ini();
} 

ppk-builder.php

$ppk_sections = [
    'section_1' => [
        'title' => 'Group One'
    ]
];

$ppk_fields = [
    'field 1' => [
        'title'   => 'Fieald One',
        'type'    => 'text',
        'section' => 'section_1',  
        'default' => 'default'
    ]
];

register_setting( 'ppk-builder', 'ppk-builder', 'ppk-builder_validate' );

    foreach ($ppk_sections as $id => $value) {
        add_settings_section( $id, $value['title'], 'ppk_section_callback', 'ppk_p');
    }

    foreach ($ppk_fields as $id => $value) {       
        add_settings_field( $id, $value['title'], 'ppk_field_callback', 'ppk_p', $value['section'], $id );
    }

function ppk_section_callback() {return null;}

function ppk_default_id( $id ) {
    global $ppk_fields;

    return $ppk_fields[ $id ]['default'];
}

function ppk_field_callback($id) {
    global $ppk_fields;

    $option = get_option('ppk-builder');
    $id_field = isset($option[$id]) ? $option[$id] : ppk_default_id($id);

    switch ($ppk_fields[$id]['type']) {
        case 'text':        
            echo '<input type="text" name="ppk-builder[' . $id . ']" value="' . $id_field . '"/>';
        break;
    }
}


settings_fields( 'ppk-builder' );
do_settings_sections( 'ppk_p' ); 
1
mrKC.988

Le problème ici est que vous n'avez jamais créé $ppk_fields en tant que variable globale.

$ppk_fields = [
    'field 1' => [
        'title'   => 'Fieald One',
        'type'    => 'text',
        'section' => 'section_1',  
        'default' => 'default'
    ]
];

Nous avons ici une variable créée normalement et obéissant à des règles de portée normales. Ce n'est pas une variable globale, et personne n'a déclaré que c'était une variable globale.

Plus bas dans le dossier, nous avons:

function ppk_field_callback($id) {
    global $ppk_fields;

Mais, la variable globale $ppk_fields est indéfinie, personne ne l’a définie. Vous devez déclarer la variable comme globale à chaque fois que vous l'utilisez, ce qui inclut la création et la destruction. Aucune exception.

Donc vous devez:

  • déclarer que la variable est globale lorsque vous la définissez à l'aide de global $ppk_fields

Mal le faire

Mais il y a un problème encore plus grand. Le plus gros problème est que vous avez utilisé des variables globales. Les variables globales sont un excellent moyen d'éviter de structurer votre programme, de briser les tests unitaires et d'introduire une complexité inutile.

Par exemple, les variables globales seraient inutiles si vous aviez placé tout le code ci-dessus dans une classe. Alors, $this->fields serait ce que vous utiliseriez.

Voici un exemple partiel:

ppk_settings.php:

class PPK_Settings {
    private $sections;
    private $fields;

    function __construct() {
        $this->sections = [
            'section_1' => [
                'title' => 'Group One'
            ]
        ];
        $this->fields = [
            'field 1' => [
                'title'   => 'Fieald One',
                'type'    => 'text',
                'section' => 'section_1',  
                'default' => 'default'
            ]
        ];
    }

    function register() {
        register_setting( 'ppk-builder', 'ppk-builder', 'ppk-builder_validate' );

        foreach ($this->sections as $id => $value) {
            add_settings_section( $id, $value['title'], array( $this, 'section_callback' ), 'ppk_p');
        }

        foreach ($this->fields as $id => $value) {       
            add_settings_field( $id, $value['title'], array( $this, 'ppk_field_callback' ), 'ppk_p', $value['section'], $id );
        }
    }

    // etc... other methods go here
}

usage:

require_once( 'ppk_settings.php' );    
$settings = new PPK_Settings();
$settings->register();

Vous pouvez plutôt utiliser le chemin OO, et avoir les objets PPK_Field et PPK_Section pour pouvoir définir vos champs, puis passer en boucle sur le tableau créant des objets, sans aucun problème ni difficulté d'accès, et sans besoin de globaux ou variables membres

2
Tom J Nowell