Två sätt att utveckla WordPress-pluggar Funktionell programmering

Denna del två i en serie som tittar på två olika programmeringsstilar (ibland kallade programmeringsparadigmer) som du kan använda när du skriver WordPress-plugin-program. I del ett Tom McFarlin omfattade objektorienterad programmering. I denna del tittar vi på funktionell programmering.

Eftersom läsarnas erfarenhetsnivå varierar kommer vi att prata om programmering på hög nivå, så om du är nybörjare, borde du inte ha något problem att följa med. Om du är en mer erfaren utvecklare, kan du hitta mer användbar information senare i artikeln.


Vad är funktionell programmering?

Funktionell programmering är förmodligen den stil som du är mest känd i - och nästan universellt - är den stil som används på de olika WordPress-kodens webbplatser som flyter runt på internet. Av den anledningen kan det ibland ses som "entry level" programmering: den stil som används av nybörjare tills de har lärt sig att behärska objektorienterad programmering. Detta är otroligt vilseledande, eftersom det är mycket enklare att använda funktionell programmering, det är inte i sig underlägsen.

Funktionell programmering betonar utvärderingen av funktioner och undviker begreppet stater eller objekt i motsats till objektorienterad programmering som uppmuntrar att tänka på kod som verkar på objekt (er), använder metoder för att ändra dessa objekt eller interagera med dem. Låt oss titta på ett mycket enkelt exempel som jämför de två stilarna:

 // Funktionsmetodfunktion add_two ($ n) return $ n +2;  $ a = 2; $ b = add_two ($ a); // $ b = 4; // Objektorienterad metod klass Nummer var $ värde = 0; funktionen __construct ($ a) $ this-> value = $ a;  funktion add_two () $ this-> value = $ this-> value +2;  $ a = nytt nummer (2); eko $ a-> värde; // Skriver 2 $ a-> add_two (); eko $ a-> värde; // Utskrifter 4

Detta mycket enkla exempel illustrerar den grundläggande skillnaden i stil för de två paradigmerna: funktionell programmering fokuserar på att överföra argument till och ta emot värden från funktioner. Det finns inga "objekt" som hanteras, bara parametrar och returvärden. Omvänt tilldelar objektorienterat tillvägagångssätt ett objekt olika egenskaper (i vårt fall ett "värde") och metoder fungerar på dessa egenskaper.


Funktioner: Grunderna

Definiera funktioner är väldigt enkelt:

 funktion add ($ number, $ number2 = 1) // Utför kod som verkar på godkända variabler $ sum = $ nummer + $ number2; // Valfritt, om det behövs kan du returnera en värdeavkastning $ summa; 

När funktionen är deklarerad kan den användas överallt i din plugin-med andra ord har den globala räckvidd.

 $ a = 4; $ b = 7; Echo add ($ a, $ b); // Utskrifter 11
Funktioner måste ha unika namn. Om du redeclarar en funktion kommer det att kasta ett fel. Eftersom din kod kommer att köras tillsammans med andra plugin-program, teman och WordPress själv borde du aldrig använda generiska namn. Istället bör du prefixa dina funktionsnamn med något unikt (som namnet på din plugin).

Du kanske har märkt det i definitionen av Lägg till, Det andra argumentet är lika med 1. Detta ställer in ett standardvärde för $ nummer2 (i det här fallet 1), och genom att göra så gör argumentet valfritt. Om argumentet inte levereras tas värdet till grundvärdet:

 echo add (4); // Skriver 5 echo add (4, 1); // Utskrifter 5

Å andra sidan finns inget standardvärde för det första värdet, så utelämnande av det här argumentet kommer att kasta ett fel

 Echo add (); // Kasta ett fel eftersom $ nummer inte är definierat

Du kan också ha ett varierande antal argument. Inuti funktionen kan vi använda func_num_args () för att få antalet argumenter mottagna, medan func_get_arg () låter dig komma åt en bestämd passerad variabel, indexerad från 0.

 funktionssumma () // Få antalet argument som ges till summan () $ number_args = func_num_args (); $ sum = 0; om (! $ number_args) returnera $ sum; för ($ i = 0; $ i < $number_args; $i++ )  $sum += func_get_arg( $i );  return $sum;  echo sum( 1, 2, 3, 4 ); //Prints 10 echo sum( 1, 2 ); //Prints 3 echo sum(); //Prints 0

Ovanstående kan också användas i objektmetoder. Slutligen, genom att deklarera en variabel som "global" kan du komma åt variabeln inuti en funktion.

 $ a = "Hej"; $ b = "World"; funktion hello_world () // Detta är nödvändigt för att komma åt $ a och $ b // deklarerat utanför funktionsomfånget. globala $ a, $ b; $ b = $ a. ". $ b; hello_world (); echo $ b; // Skriv ut 'Hello World'
Att använda globals är generellt avskräckt. Särskilt eftersom två plugin-program som använder samma namn för en global variabel kan orsaka att en eller båda plugin-programmen bryts. Om du måste använda en global variabel, se till att den är unik genom att prefixa med ditt plugin-namn.

Varför använda funktionell programmering?

Att bestämma vilken programmeringsstil som ska användas kommer ner till dom - och ja - personlig preferens. Det är inte mer rätt eller fel att använda funktionell över objektorienterad programmering, men oftare än det finns en stil som passar bättre för det du försöker uppnå.

Ibland är objektorienterad programmering helt enkelt inte nödvändig, och bara över komplicerar saker eller introducerar överflödig kod. Ett exempel kan vara de olika "verktygsfunktionerna" som WordPress tillhandahåller. Dessa är generiska funktioner som tjänar till att utföra ett visst syfte. Till exempel wp_trim_words ($ text, $ num_words) enkelt trimmer den givna strängen till en viss storlek (i ord). Det skulle inte lägga till något som ska definieras wp_trim_words () i stället som en metod som tillhör ett visst objekt, och skulle resultera i fula kod. Med funktionell programmering tar det en rad.

En fördel med funktionell programmering, särskilt för nybörjare, är dess enkelhet. Du behöver inte oroa dig för statiska, privata eller skyddade funktioner - de är alla globala. Inte heller finns begreppet statiska variabler. På grundnivåen returnerar din funktion en produktion som härrör från vad du har gett den. Till exempel, get_the_title (7) kommer att returnera titeln för posten med ID 7.

En annan fördel med funktionell programmering är att funktionerna är tillgängliga globalt. Med objektorienterade program måste du passera det objektet för att kunna agera på ett visst objekt. Detta kan ibland vara knepigt. För att illustrera detta låt oss ta ett exempel från första delen:

 klass DemoPlugin public function __construct () add_action ('wp_enqueue_scripts', array ($ this, 'register_plugin_scripts'));  offentlig funktion register_plugin_scripts () // Registrera plugin skript $ demo_plugin = nya DemoPlugin ();

När WordPress lagrar register_plugin_scripts () metod så att den kan ringas när wp_enqueue_scripts åtgärd utlöses gör det genom att referera inte bara till metoden utan även av objektet $ demo_plugin. Detta beror på att samma metod för olika instanser av ett objekt beaktas annorlunda metoder - det vill säga, $ Demo_plugin-> register_plugin_scripts () och $ Copy_of_demo_plugin-> register_plugin_scripts () är inte samma. Detta kan tyckas udda - men metoder kan uppträda olika för olika fall av samma klass, så vi behöver referera till både metod och exempel.

Men varför är det här? Det gör det väldigt svårt för en tredjeparts plugin eller ett tema att ta bort den metoden, eftersom de skulle behöva ringa:

 remove_action ('wp_enqueue_scripts', array ($ demo_plugin, 'register_plugin_scripts'));

Men i allmänhet kommer de inte ha tillgång till $ demo_plugin variabel. (Obs: om metoden är deklarerad statisk, så kan du komma runt detta).


Objektorienterad och funktionell programmering i WordPress

Naturligtvis har objektorienterad programmering sina fördelar, som diskuteras i del ett. Som Tom också nämnde är det oundvikligt när man använder WordPress 'widget API. Ett annat vanligt exempel är WP_Query (). Här är ett objektorienterat tillvägagångssätt klart det bästa: du har ett objekt (i det här fallet en fråga), som har olika egenskaper (dvs sökkriterier, paginationsinformation, matchande resultat) och du vill agera på den frågan (analysera den, generera och sanitera motsvarande SQL, och returnera resultaten).

WP_Query () visar hur kraftfull objektorienterad programmering kan vara när den används korrekt. Efter att ha initierat frågan:

 $ the_query = nya WP_Query (array (...));

Du kan inte bara få tillgång till resultaten utan också annan information, till exempel, paginationsvärden: hur många sidor av resultat det finns, vilken sida som visas, totalt antal resultat och typen av fråga, t.ex.. ($ The_query-> is_search), $ The_query-> is_single () etc. Det finns också hela "loop" -infrastrukturen.

 om ($ the_query-> have_posts ()) echo '
    '; medan ($ the_query-> have_posts ()): $ the_query-> the_post (); // Loop echo "
  • '. get_the_title ($ the_post-> ID). '
  • '; EndWhile; eko "
'; wp_reset_postdata ();

Vilken gömmer allt internt jonglering av resultat och globals bakom ett mänskligt vänligt API.

Så då get_posts ()? Detta tjänar bara som en omslag för WP_Query (), och returnerar helt enkelt en rad inlägg som matchar frågan. Som sådan får du inte "bells and whistles" of WP_Query (), men det är lite effektivare. Så om du ska använda get_posts () eller WP_Query () beror på användningsfallet (till exempel om du behöver paginering eller inte), men det är också nere för personliga preferenser.

 $ results = get_posts (array (...)); om ($ resultat) echo '
    '; foreach ($ resultat som $ the_post) echo '
  • '. get_the_title ($ the_post-> ID). '
  • '; eko
';

Sammanfattning

Förhoppningsvis har dessa två artiklar hjälpt till att lyfta fram fördelarna och nackdelarna med dessa programmeringsstilar. Ta bort punkten är att det inte finns något rätt och fel här, och varje programmerare kommer att ha sin egen personliga preferens. Men vissa kontext låter sig lättare till en viss programmeringsstil - och som sådan borde du förvänta dig att din plug-in innehåller en blandning av båda.