Kuinka asettaa ja käyttää globaaleja muuttujia? Tai miksi ei käyttää niitä lainkaan

PÄIVITYS: Alkuperäinen kysymykseni on ratkaistu, mutta tästä on tulossa pätevä keskustelu siitä, miksi en käyttäisi globaaleja muuttujia, joten päivitän kysymystä vastaamaan sitä. Ratkaisu oli <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?> kuten @TomJNowell ehdotti.

PÄIVITYS 2: Minulla on nyt se tekemässä juuri sitä, mitä halusin. Mutta käytän edelleen globaalia ulottuvuutta ja olisin iloinen voidessani löytää paremman tavan.

Yritän luoda kokonaisen joukon globaaleja muuttujia pysyville linkeille luokkiin, joita käytetään useissa paikoissani. teema. Tärkein syy tähän on käyttö sekä päävalikossa että sarjassa alisuuntauksia, jotka valitaan sen mukaan, mihin luokkaan nykyinen viesti kuuluu. Tämä ei ole teema Tulen julkaisemaan muiden käyttöön, mutta se on rakennettu yhtä hyvin tiettyä tarkoitusta varten.

Tällä tavalla luon niitä tällä hetkellä (olen liittänyt vain muutamaan muuttujasta).

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" ); 

Voin nyt tehdä <?php global $prop; echo $prop; ?> 4 paikassa, jotka menevät ja saada takaisin koodin koko linkki. Kun se muuttuu, minun on vaihdettava se vain yhdessä paikassa. Olen avoin vaihtoehdoille, jotka eivät sisällä maailmanlaajuista ulottuvuutta.

Kommentit

  • Minkä linkin tämä lausunto toistaa esc_url ($ category_link_prop); näyttää ? Mikä on odotettu linkkisi?
  • Miksi et käytä vain ’ get_cat_ID (****) ’ missä ikinä aiot käyttää globaalia muuttujaa. Epäilen, että sillä olisi mitään nopeusetua, jolla teet sen. Luettavuuden kannalta ’ get_cat_ID (****) ’ voittaa kädet alas.
  • Voitko kirjoittaa sanan uudelleen? Luin kysymyksesi ja olen ’ vielä epävarma siitä, mitä sinä haluat tehdä ja miksi haluat tehdä sen. Yleinen neuvoni olisi olla käyttämättä globaaleja muuttujia äläkä pilaamaan globaalia ulottuvuutta
  • tämä kuulostaa vähän kuin X / Y-ongelma . Ehkä sinun kannattaa varmuuskopioida ja selittää tarkalleen mikä on toivottu lopputulos. Olen ’ olen varma t täällä ’ on paljon tyylikkäämpi ratkaisu kuin asettaa joukko globaaleja muunnelmia vain kovakoodiviittauksiksi niihin muussa navissa
  • luoda toiminto, joka tuottaa valikkosi sillä välitetyn kontekstin perusteella voit pitää kaikki valikkologiikat ja niihin liittyvät muuttujat kapseloituna yhdessä paikassa.

Vastaa

Vaikka suosittelen tätä voimakkaasti, se ei nopeuta asioita, käyttösi on virheellinen.

WordPress välimuisti nämä asiat jo välimuistissa, sinun ei tarvitse tallentaa tulosta ja käyttää uudelleen, WP tekee sen jo .

Todennäköisesti koodisi toimii hitaammin tämän mikrooptimoinnin seurauksena, ei nopeammin!

Kuinka käyttää globaaleja

Kun yrität käyttää yleistä, sinun on ensin määritettävä global -avainsana. Olet määrittänyt sen tässä määritellessäsi sen arvoa, mutta kyseisen alueen ulkopuolella se on ilmoitettava uudelleen globaalina laajuusmuuttujana.

esim. functions.php:

  function test() { global $hello; $hello = "hello world"; } add_action( "after_setup_theme", "test" );  

Kohdassa single.php tämä ei toimi:

  echo $hello;  

Koska $hello on määrittelemätön. Tämä kuitenkin toimii :

  global $hello; echo $hello;  

Älä tietenkään tee kumpaakaan. WordPress yrittää jo tallentaa välimuistiin nämä asiat välimuistiin .

Globaalien muuttujien haitat ja vaarat

Et näe nopeuden kasvua tekemällä tätä (saatat nähdä pienen nopeuden laskun), saat vain monimutkaisuuden ja tarpeen kirjoittaa paljon globaaleja ilmoituksia, joita ei tarvita.

Sinulla on myös muita ongelmia:

  • koodi, jota on mahdotonta kirjoittaa testejä
  • koodille, joka käyttäytyy eri tavalla joka kerta kun se suoritetaan
  • törmää muuttujien nimiin jaetusta nimiavaruudesta
  • tahattomia virheitä unohtamatta julistaa global
  • rakenne koodisi tietovarastoon
  • ja paljon muuta

Mitä sinun pitäisi käyttää sen sijaan?

Sinun olisi parempi käyttää strukturoitua dataa, kuten esineinä tai riippuvuusinjektiona tai sinun tapauksessasi joukko toimintoja.

Staattiset muuttujat

Staattiset muuttujat eivät ole hyviä, mutta ajattele heitä globaalien muuttujien hieman vähemmän pahoina serkkuina.Staattiset muuttujat ovat globaaleja muuttujia, mikä mutaa peittävä leipä on syanidia.

Tässä on esimerkiksi tapa tehdä jotain vastaavaa staattisten muuttujien kautta, esim.

  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  

Singletonit

Singletonit ovat kuin staattisia muuttujia, paitsi että luokka sisältää staattisen muuttujan kyseisen luokan esiintymän kanssa . Ne ovat yhtä pahoja kuin globaalit muuttujat, vain eri syntaksilla. Vältä niitä.

WP_Cache, asia, jonka yritit tehdä, mutta WP jo tekee sen

Jos todella haluat säästää aikaa tallentamalla tietoja jonnekin uudelleenkäyttöä varten. Harkitse WP_Cache -järjestelmän käyttöä wp_cache_get jne. esim.

 $value = wp_cache_get( "hello" ); if ( false === $value ) { // not found, set the default value wp_cache_set( "hello", "world" ); }  

Nyt arvo tallennetaan välimuistiin WordPressin koko pyynnön ajan, se näkyy virheenkorjaustyökaluissa ja jos sinulla on objektin välimuisti, se ”jatkuu pyyntöjen aikana.


Sidelote 1: Huomaan, että jotkut ihmiset yrittävät säilyttää tietoja globaaleissa muuttujissa pyyntöjen aikana tietämättä, että PHP ei toimi näin . Toisin kuin Node-sovellus, kukin pyyntö lataa uuden kopion sovelluksesta, joka sitten kuolee, kun pyyntö on valmis. Tästä syystä yhdelle pyynnölle asetetut globaalit muuttujat eivät selviä seuraavasta pyynnöstä.

Sidenote 2: Päivitetyn kysymyksen perusteella globaalit muuttujat eivät tuota sinulle minkäänlaista suorituskykyä. Sinun tulisi vain luoda HTML, kun tarvitset sitä, ja se toimii yhtä nopeasti, ehkä jopa hieman nopeammin. Tämä on mikrooptimointi.

Kommentit

  • Tiedän sen ’ saunan pähkinöitä käyttämään globaalia laajuutta, mutta useimpia, ellei kaikkia näitä muuttujia käytetään kaikilla sivuilla. Olen ’ avoin paremmille ideoille. Aion muokata kysymystä, jotta aikomukseni olisi hieman selvempi. BTW se toimii täysin hyvin, kun teen <?php global $category_link_prop; echo esc_url( $category_link_prop ); ?> ehdotuksesi mukaisesti. Kiitos!
  • Ah, jos ratkaisuni toimii, voisitko merkitä hyväksytyksi? Globaalit muuttujat ovat yhtä nopeita kuin alkuperäisen puhelun soittaminen, voit kokeilla sen sijaan toimintoja, joten sinun ei ’ tarvitse kirjoittaa 2 riviä, vielä parempi, singletti, vielä parempi, tee kaikki tämä dynaaminen ja malliosaan, joka sisältyy get_template_part-sivulle.
  • Merkitty hyväksytyksi sillä, mitä teen nyt, vaikka voin mennä johonkin strategioista, joita @MarkKaplun ehdottaa alla. Get_template_part () on mielenkiintoinen idea, mutta en ’ ole varma, että haluan, että minulla on täynnä sellaisia lyhyitä tiedostoja sisältävä tiedosto …
  • oooh no ei, et halua ’ et halua tiedostoa kullekin luokalle, haluat ’ haluat vain sen, joka nappaa nykyisen luokan nimen ja käyttää sitä . Sinun ei pitäisi ’ sinun tarvitse koodata mitään, kuvittele vaivaa kaiken kovakoodauksella
  • Laitoin koodin aktiiviseen child-functions.php -ohjelmaan. Mutta en voi käyttää muuttujaa php-include-tiedostossa, johon soitan ” normaalista ” tietokannan luomasta viestistä. Kerro minulle, mitä teen väärin? (Määritän sen tietysti globaaliksi.)

Vastaa

Älä käytä yleisiä muuttujia , niin yksinkertaista.

Miksi et käytä globaaleja

Koska globaalien käyttö vaikeuttaa ohjelmiston ylläpitoa pitkällä aikavälillä.

  • globaali voidaan ilmoittaa missä tahansa koodissa tai missään lainkaan, siksi ei ole paikkaa, jossa voit vaistomaisesti katsoa löytääksesi kommentin mihin globaalia käytetään
  • Koodia lukiessasi oletat yleensä, että muuttujat ovat paikallisia funktiolle, eivätkä ymmärrä, että niiden arvon muuttaminen funktiossa saattaa muuttaa koko järjestelmää.
  • Jos ne eivät käsittele syötettä, funktioiden tulisi palauttaa sama arvo / lähtö, kun ne Globaalien käyttö funktiossa tuo käyttöön lisäparametreja, joita ei ole dokumentti funktiodeklaraatiossa .
  • globaaleilla ei ole mitään erityistä alustusrakennetta, joten et voi koskaan olla varma milloin pääset globaalin arvoon, etkä saa virheitä yrittäessäsi käyttää globaalia ennen alustusta .
  • Joku muu (ehkä laajennus) saattaa käyttää samannimisiä globaaleja, pilata koodisi tai pilata sen alustusjärjestyksestä riippuen.

WordPress-ytimessä on tapa tapa tapa paljoa maailmanlaajuisten asiakkaiden käyttöön. Yrität ymmärtää, kuinka perustoiminnot, kuten the_content, toimivat, yhtäkkiä huomaat, että $more -muuttuja ei ole paikallinen, mutta globaali ja sen on etsittävä kokonaisuutena. ydintiedostoista ymmärtääksesi milloin se asetetaan tosi.

Mitä voidaan tehdä, kun yritetään lopettaa kopiointi & useiden koodirivien liittämisestä sen sijaan, että ensimmäisen ajon tulos tallennettaisiin globaaliin? On olemassa useita lähestymistapoja, toiminnallisia ja OOP.

Makeutusainetoiminto. Se on yksinkertaisesti kääre / makro kopioinnin / liittämisen tallentamiseksi.

// input: $id - the category id // returns: the foo2 value of the category function notaglobal($id) { $a = foo1($id); $b = foo2($a); return $b; } 

Edut ovat, että nyt on olemassa dokumentaatio siitä, mitä entinen globaali tekee, ja sinä sinulla on selvä kohta virheenkorjaukseen, kun palautettava arvo ei ole odotettu arvo.

Kun sinulla on makeutusaine, tulos on helppo tallentaa välimuistiin tarvittaessa (tee se vain, jos huomaat, että tämä toiminto vie pitkä aika suorittaa)

function notaglobal($id) { static $cache; if (!isset($cache)) { $a = foo1($id); $b = foo2($a); $cache = $b; } return $cache; } 

Tämä antaa sinulle saman globaalin käyttäytymisen, mutta sillä etulla, että sinulla on varma alustus joka kerta, kun sitä käytetään.

OOP: lla voi olla samanlaisia kuvioita. Mielestäni OOP ei yleensä lisää mitään lisäosia ja teemoja, mutta tämä on erilainen keskustelu.

class notaglobal { var latestfoo2; __constructor($id) { $a = foo1($id); $this->latestfoo2 = foo2($a) } } $v = new notaglobal($cat_id); echo $v->latestfoo2; 

Tämä on kömpelö koodi, mutta jos on useita arvoja, jotka haluat laskea ennakolta, koska niitä käytetään aina, tämä voi olla tapa edetä. Pohjimmiltaan tämä on objekti, joka sisältää kaikki globaalisi alueesi järjestäytyneellä tavalla. Välttääksesi tämän objektin esiintymän tekemisen globaaliksi (haluat vain yhden esiintymän, muuten lasket arvot uudelleen). kannattaa ehkä käyttää singleton-mallia (jotkut väittävät, että se on huono idea, YMMV)

En halua käyttää objektimääritettä suoraan, joten koodissani se kirjoittaa vielä joitain

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

kommentteja

  • Älä ’ älä huuda . Haluatko selittää miksi ja antaa jonkinlaisen lainauksen?
  • Luulen, että ymmärrät väärin vastauksen. Jos hän ei yrittänyt ’ yrittää tehdä varhaista optimointia tallentamalla arvoja globaaleihin muuttujiin, hänen koodinsa olisi toiminut. Huutaminen johtuu siitä, että vakiintuneiden ohjelmistokehitysperiaatteiden noudattaminen on asia, jota ’ ei voida korostaa tarpeeksi. Ihmiset, jotka eivät ymmärrä näitä perusperiaatteita (saatavilla paikallisessa Googlessa), eivät saa levittää koodia verkossa.
  • IMO on vastaus, Googlesta tänne tulevien ihmisten tulisi nähdä, että se on huono idea jopa ajatella globaalien käyttämistä heti.
  • Se ’ ei riitä sanomaan älä tee X: tä, sinun on selitettävä miksi tai näytät siltä kuin sinä ’ sanon sen uudelleen mielijohteella
  • @TomJNowell, minusta on hauskaa, että vain minä aloin äänestää itse kysymystä, koska se ei tietenkään kuulunut kysymyksen piiriin. WASE. En nähnyt ’ näen arvon laajentamista aiheeseen, jota ei olisi pitänyt aloittaa täällä ollenkaan.

Vastaa

Kysymyksesi liittyy php: n toimintaan.

Ota esimerkkinä $ wpdb esimerkki

$ wpdb on tunnettu globaali muuttuja.

Tiedätkö, milloin se ilmoitetaan ja määritetään arvoilla?

Jokainen sivu ladattiin , kyllä, aina kun vierailet WordPress-sivustollasi.

Vastaavasti sinun on varmistettava, että muuttujat, jotka haluat globalisoida, ilmoitetaan ja niille määritetään vastaavat arvot jokaisella ladatulla sivulla.

Vaikka en ole teeman suunnittelija, voin kertoa, että after_setup_theme on yksi ajan koukku. se käynnistyy vain, kun teema on aktivoitu.

Jos olisin sinä, käytän initia tai muita koukkuja. Ei, jos olisin sinä, en käytä lainkaan globaaleja muuttujia …

En todellakaan osaa selittää asioita. Joten sinun pitäisi noutaa kirja, jos haluat sukeltaa PHP: hen.

Vastaa

Voit aina käyttää yksittäistä mallia staattisten vetimien kautta.

<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 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *