MISE À JOUR: / Ma question initiale a été résolue, mais cela se transforme en une discussion valable sur la raison pour laquelle il ne faut pas utiliser de variables globales. Je suis donc en train de mettre à jour la question pour refléter cela. La solution était <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?>
, comme suggéré par @TomJNowell.
UPDATE 2: Je l'ai maintenant faire exactement ce que je voulais. Mais j'utilise toujours la portée mondiale et serais heureux de trouver un meilleur moyen.
J'essaie de mettre en place toute une série de variables globales pour les liens permanents aux catégories à utiliser à différents endroits de mon thème. La raison principale en est l'utilisation dans la navigation principale, ainsi que dans une série de sous-navigations choisies en fonction de la catégorie dans laquelle se trouve la publication actuelle. Ce n'est pas un thème que je vais aborder libérer pour une utilisation par d'autres, mais est construit pour un but très spécifique.
C’est ainsi que je les crée actuellement (je n’ai collé que dans quelques-unes des variables).
function set_global_nav_var()
{
//proposal
global $prop;
// Get the ID of a given category
$category_id_prop = get_cat_ID( 'proposal' );
// Get the URL of this category
$category_link_prop = get_category_link( $category_id_prop );
$prop = '<a href="' .esc_url( $category_link_prop ). '" title="Proposal">Proposal</a>';
//Calvinball
global $cb;
// Get the ID of a given category
$category_id_cb = get_cat_ID( 'calvinball' );
// Get the URL of this category
$category_link_cb = get_category_link( $category_id_cb );
$cb = '<a href="' .esc_url( $category_link_cb). '" title="Calvinball">Calvinball</a>';
}
add_action( 'init', 'set_global_nav_var' );
Je peux maintenant faire <?php global $prop; echo $prop; ?>
int il 4 endroits qui vont et récupérer le lien entier pour le code. Lorsque cela change, je n’ai plus qu’à le changer. Je suis ouvert aux alternatives qui n'impliquent pas la portée globale.
Bien que je déconseille fortement cela, et que cela ne va pas accélérer les choses, votre utilisation est incorrecte.
Lorsque vous essayez d'utiliser un global, vous devez d'abord spécifier le mot clé global. Vous l'avez spécifié ici lors de la définition de sa valeur, mais en dehors de cette portée, il doit être redéclaré en tant que variable de portée globale.
par exemple. dans functions.php:
function test() {
global $hello;
$hello = 'hello world';
}
add_action( 'after_theme_setup', 'test' );
Dans single.php, cela ne fonctionnera pas:
echo $hello;
Parce que $ hello est indéfini. Ceci cependant fonctionnera travaillera:
global $hello;
echo $hello;
Bien sûr, vous ne devriez faire ni l'un ni l'autre. WordPress tente déjà de mettre ces objets en cache dans le cache d'objets. Cela n'augmentera pas la vitesse (vous constaterez peut-être une faible diminution de la vitesse), tout ce que vous obtiendrez sera une complexité supplémentaire et la nécessité de taper un grand nombre de déclarations globales non nécessaires.
Vous feriez mieux d'utiliser des données structurées, telles que des objets ou une injection de dépendance, ou dans votre cas, un ensemble de fonctions.
Par exemple, voici un moyen de faire quelque chose de similaire via des variables statiques (toujours mauvaises pour les mêmes raisons, mais un peu moins, et plus faciles à taper), par exemple.
function awful_function( $new_hello='' ) {
static $hello;
if ( !empty( $new_hello ) ) {
$hello = $new_hello;
}
return $hello;
}
awful_function( 'telephone' );
echo awful_function(); // prints telephone
awful_function( 'banana');
echo awful_function(); // prints banana
Si vous voulez vraiment gagner du temps en stockant les données à réutiliser, envisagez d’utiliser le système WP_Cache
avec wp_cache_get
etc.
N'utilisez pas de variables globales , aussi simple que cela.
Pourquoi ne pas utiliser globals
Parce que l'utilisation de globals rend plus difficile la maintenance du logiciel à long terme.
Le noyau WordPress a beaucoup trop recours aux globals. Tout en essayant de comprendre le fonctionnement de fonctions de base telles que the_content
, vous réalisez soudain que la variable $more
n’est pas locale, mais globale. Vous devez donc rechercher l’ensemble des fichiers de base pour comprendre quand elle est définie sur true.
Alors, que peut-on faire en essayant d’arrêter de copier-coller de plusieurs lignes de code au lieu de stocker le résultat de la première exécution dans un résultat global? Il existe plusieurs approches, fonctionnelle et POO.
La fonction édulcorant. C’est simplement un wrapper/macro pour sauvegarder le copier/coller
// input: $id - the category id
// returns: the foo2 value of the category
function notaglobal($id) {
$a = foo1($id);
$b = foo2($a);
return $b;
}
Les avantages sont qu’il existe désormais une documentation sur ce que fait l’ancien global et que vous avez un intérêt évident à déboguer lorsque la valeur renvoyée n’est pas celle que vous attendez.
Une fois que vous avez un édulcorant, il est facile de mettre en cache le résultat si nécessaire (ne le faites que si vous découvrez que l'exécution de cette fonction prend beaucoup de temps)
function notaglobal($id) {
static $cache;
if (!isset($cache)) {
$a = foo1($id);
$b = foo2($a);
$cache = $b;
}
return $cache;
}
Cela vous donne le même comportement qu'un global mais avec l'avantage d'avoir une initialisation assurée à chaque fois que vous y accédez.
Vous pouvez avoir des modèles similaires avec la POO. Je trouve que OOP n'ajoute généralement aucune valeur aux plugins et aux thèmes, mais il s'agit d'une discussion différente.
class notaglobal {
var latestfoo2;
__constructor($id) {
$a = foo1($id);
$this->latestfoo2 = foo2($a)
}
}
$v = new notaglobal($cat_id);
echo $v->latestfoo2;
C'est un code plus maladroit, mais si vous souhaitez précalculer plusieurs valeurs parce qu'elles sont toujours utilisées, cela peut être une solution. Fondamentalement, il s'agit d'un objet qui contient tous vos globals de manière organisée. Pour éviter de rendre une instance de cet objet globale (vous voulez une instance sinon vous recalculez les valeurs), vous pouvez utiliser un modèle singleton pattern (certaines personnes soutiennent que c'est une mauvaise idée, YMMV).
Je n'aime pas accéder directement à un attribut d'objet, donc dans mon code, il va se déformer davantage
class notaglobal {
var latestfoo2;
__constructor() {}
foo2($id) {
if (!isset($this->latestfoo2)) {
$a = foo1($id);
$b = foo2($a);
$this->latestfoo2= $b;
}
return $this->latestfoo2;
}
}
$v = new notaglobal();
echo $v->foo2($cat_id);
Votre question concerne le fonctionnement de php.
Prenons $ wpdb par exemple
$ wpdb est une variable globale bien connue.
Savez-vous quand il sera déclaré et attribué avec des valeurs?
Chaque page chargée , ouais, chaque fois que vous visitez votre site wordpress.
De même, vous devez vous assurer que les variables à globaliser seront déclarées et affectées avec les valeurs correspondantes à chaque page chargée.
Bien que je ne sois pas un concepteur de thème, je peux dire que after_setup_theme est un crochet unique. il ne sera déclenché que lorsque le thème sera activé.
Si j'étais vous, j'utiliserais init ou d'autres hooks. Non, si j'étais vous, je n'utiliserai pas de variables globales ...
Je ne suis vraiment pas bon pour expliquer les choses. Vous devriez donc choisir un livre si vous voulez explorer PHP.
Vous pouvez toujours utiliser un motif singleton via des accesseurs statiques.
<ul>
<li><?php echo MyGlobals::get_nav_prop( 'proposal' )[ 'html' ]; ?></li>
<li><?php echo MyGlobals::get_nav_prop( 'calvinball', 'html' ); ?></li>
</ul>
<?php
if ( ! class_exists('MyGlobals') ):
class MyGlobals {
public $props;
public function __construct(){
$this->props = array (
'proposal' => array( 'title' => 'Proposal', 'text' => 'Proposal' ),
'calvinball' => array( 'title' => 'Calvinball', 'text' => 'Calvinball' ),
);
}
public function get_nav_prop ( $term, $prop = false )
{
$o = self::instance();
if ( ! isset( $o->props[$term] ) ) { return falst; }
if ( ! isset( $o->props[$term][ 'html' ] ) ) {
$id = get_cat_ID( $term );
$link = esc_url ( get_category_link( $id ) );
$title = $o->props[$term]['title'];
$text = $o->props[$term]['text'];
$o->props[$term]['html'] = '<a href="'.$link.'" title="'.$title.'">'.$text.'</a>';
$o->props[$term]['link'] = $link;
$o->props[$term]['id'] = $id;
}
if($prop){ return isset($o->props[$term][$prop]) ? $o->props[$term][$prop] : null; }
return $o->props[$term];
}
// -------------------------------------
private static $_instance;
public static function instance(){
if(!isset(self::$_instance)) {
self::$_instance = new MyGlobals();
}
return self::$_instance;
}
}
endif; // end MyGlobals