Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Pro _ Metaprogramowanie w PHP

Napisany przez: kwiateusz 21.05.2008, 16:56:51

Na prośbę empathon'a zakładam niniejszy temat smile.gif

Napisany przez: LoPMX 24.06.2008, 19:04:47

Czegos takiego nie ma smile.gif

Zapraszam na http://www.ruby-lang.org winksmiley.jpg

Napisany przez: radex_p 24.06.2008, 19:06:20

http://pl.wikipedia.org/wiki/Metaprogramowanie

"Metaprogramowanie może polegać nie tylko na generowaniu kodu, ale również na modyfikacjach w czasie wykonania programu. Takie możliwości dają języki LISP, Smalltalk, PHP, Python, Ruby oraz Perl."

http://en.wikipedia.org/wiki/Metaprogramming

"Not all metaprogramming involves generative programming. If programs are modifiable at runtime (such as in Lisp, Python, REBOL, Smalltalk, Ruby, PHP, Perl, Tcl, Lua, and JavaScript), then techniques can be used to perform metaprogramming without actually generating source code."

Napisany przez: LoPMX 24.06.2008, 19:37:20

Tzn. ze uwazasz

  1. <?php
  2. $class_name = 'Article'; $article = new $article;
  3. ?>


za metaprogramowanie?

Napisany przez: Cysiaczek 24.06.2008, 19:42:21

@LoPMX - nie, to jest wykorzystanie możliwości składni języka w służbie polimorfizmu smile.gif

metaprogramowanie natomiast... http://pl2.php.net/manual/pl/ref.classkit.php

Pozdrawiam

Napisany przez: LoPMX 24.06.2008, 20:06:48

@ Cysiaczek : Ale po co podsylasz oczywiste linki?

Prawda jest taka, ze jest to czyste naciaganie, by nadarzac za trendem.

PHP od srodka jest kiepskim jezykiem, balaganiarskim. Ale skoro uwazasz, ze chcesz uzywac tak ubogiego i malo elastycznego API to... powodzenia.

Napisany przez: mike 24.06.2008, 20:08:33

W PHP można bardzo dobrze symulować metaprogramowanie.
http://interfacelab.com/metadataattributes-in-php/ Nie sa to możliwości Javy ale też coś.

Napisany przez: Sedziwoj 30.06.2008, 08:56:19

Cytat(LoPMX @ 24.06.2008, 21:06:48 ) *
PHP od srodka jest kiepskim jezykiem, balaganiarskim. Ale skoro uwazasz, ze chcesz uzywac tak ubogiego i malo elastycznego API to... powodzenia.


To chyba niezbyt ma się z tematem, jak nie chcesz pisać w PHP, to nie pisz, ale nie zaśmiecaj tematów.

@mike
Ciekawy link.
Nie wiem dlaczego ale jakoś mi ten sposób się nie podoba. Bo to jest pobieranie informacji poza interfejsem obiektowym, takie definiowanie właściwości poza kodem źródłowym.
Jak zawsze trzeba uważać wszystkim co jest trendi, bo potem może wyjść, że nie jest tak fajne jak to malowali. Bo przecież w pisaniu kodu nie chodzi tylko aby jak najszybciej go napisać, jeszcze mamy aby był czytelny, łatwo modyfikowalny (jak również aby dało się go przetestować)

Napisany przez: splatch 2.07.2008, 07:22:11

Jakiś czas temu pisałem o http://blog.dywicki.pl/2008/01/20/adnotacje-w-javie-i-w-php/. Jest to nieco wygodniejsze niż http://interfacelab.com/metadataattributes-in-php/. Można na podstawie tego narzędzia napisać kolejny generator ale nie będzie też problemu żeby wykorzystywać adnotacje w czasie działania (Reflection API).

LoPMX propagandy na rzecz Ruby nie potrzebujemy, jest dosyć tego śmiecia w Internecie.

Napisany przez: wrzasq 3.07.2008, 11:41:43

a ja sie zgadzam z LoPMX (nie tylko w tym, ze PHP jest nieuporzadkowane - lekkie stwierdzenie - ale tez, ze w PHP metaprgramowania nie ma). i nie robie zadnej propagandy na rzecz innych jezykow, bo pisze glownie wlasnie w PHP tongue.gif, a juz na pewno nie na rzecz Ruby, bo nigdy go nie uzywalem (jeszcze).

przynajmniej w samym PHP. chyba, ze by podciagnac pod to http://www.php.net/eval. oczywiscie jest rozszerzenie classkit (ale jest to stare rozwiazanie, znacznie bardziej rozwiniete jest http://www.php.net/manual/pl/book.runkit.php) wspomniane przez Cysiaczka, no ale rownie dobrze mozna powiedziec, ze PHP umozliwia przeciazanie operatorow, bo jest rozszerzenie http://pecl.php.net/package/operator.

natomiast co do adnotacji, czy ReflectionAPI to nie do konca jest to zgodne z definicja metaprogramowania. poniewaz to nie generuje zadnego kodu, pozwala jedynie odczytywac informacje o juz istniejacym. ReflectionAPI to nic wiecej jak reverse engineering.

aczkolwiek zastanawiajaca mogla by byc taka technika:

  1. <?php
  2.  
  3. $id = http://www.php.net/uniqid();
  4.  
  5. $content = '<?php
  6.  
  7. /* tutaj kod wygenerowany na podstawie jakichs informacji */
  8.  
  9. ?>';
  10.  
  11. file_put_contents($id . '.php', $content);
  12.  
  13. include($id . '.php');
  14.  
  15. http://www.php.net/unlink($id . '.php');
  16.  
  17. ?>


(hah, chyba sam sobie zaprzeczylem ;P)

Napisany przez: mike 3.07.2008, 11:48:28

~wrzasq a może zamiast pisać posty w odpowiedzi na coś co Ci się uroiło napisz odpowiedź na to co zostało powiedziane tongue.gif winksmiley.jpg
Nikt nie twierdzi, że w PHP można meta programować, bo to oczywista nieprawda.

Podane przykłady to przykłady gdzie takie lub podobne zachowanie jest zaledwie symulowane. Przecież w żadnym z powyższych postów nikt nie twierdzi (poza głupią wikipedią, ale ją olewamy), że to jest meta programowanie.

Napisany przez: Kocurro 25.07.2008, 10:37:59

Pozwolicie drodzy koledzy, że włączę się w tą dyskusję. Najpierw jednak chciałbym Was prosić o wyjaśnienie co rozumiecie pod pojęciem metaprogramowanie. Pytam ponieważ śmiem się nie zgadzać z opinią, że takie coś nie istnieje, ale być może cała rzecz rozchodziłaby się o rozumienie tego pojęcia.

Pozdrawiam,
Łukasz

Napisany przez: orglee 25.07.2008, 21:10:00

No ja właśnie nie mam pojęcia co to jest, ale z definicji podanej przez radex'a
mam wrażenie że metaprogramowaniem jest na przykład cache pakietu smarty,
który generuje wykonywalny kod PHP ze swoich tagów.

edit>
Chociaż z drugiej strony wydaje mi się to ostro naciągane po przeczytaniu wstępu z http://www.php.net/manual/pl/intro.runkit.php

Napisany przez: Tubis 26.07.2008, 11:29:42

IMHO Metaprogramowanie jest to uzupełnianie aplikacji "dodatkowymi funkcjonalnościami" już w czasie jej działania. Np. mechanizm active record pobiera z bazy danych informacje o polach w tabeli i na ich podstawie tworzy findery.

Napisany przez: nasty 9.08.2008, 22:48:45

Z tego co zauważyłem, nie do końca wszyscy się zgadzają na temat tego co to jest meta-programowanie. Zacznę możne, wiec od przedstawienia mojego rozumowania tego terminu.

Otóż, metaprogramming bierze się z słowa metadata. Wg. wikipedia, metadata to jest "data about data" czyli dane opisujące czym są jakieś dane. Najprostszym przykładem (możne nie tak oczywistym) jest tabela danych w bazie danych. Faktyczne dane są zapisywane w tej tabeli w wierszach i kolumnach, ale dodatkowo dla kazdej tabeli jest opisywane kodowanie znaków, silnik obsługujący te dane, informacje te tak naprawdę w żaden logiczny sposób nie są powiązane z faktycznymi danymi, bo np. jaki się nazywa tabela, jakie jest kodowanie znaków tak naprawdę z logicznego punktu widzenia nie ma nic wspólnego z nazwa użytkownika, z nazwa/ilością produktów itd... ale informacje te są niezbędne do działania systemy gdyż, np. pozwalają dobrać odpowiedni algorytm sortowania, czy np. bez informacji o silniku obsługiwania tej tabeli nie jesteśmy w stanie obsłużyć tych danych.

Metaprogramowanie imo, jest to dodawanie dodatkowych informacji o już istniejących strukturach danych, blokach kodu, klasach i/lub innych obiektach (nie chodzi mi o znaczenia tego słowa z perspektywy programowania obiektowego). Przekładając to na programowanie obiektowe (bo nie spotkałem się z pojęciem metaprogramowania w przypadku programowania strukturalnego), jest to dodawanie nowej funkcjonalności, badz tez "wstrzykiwania" jej do już istniejącego kodu bez ingerencji w sama jego strukturę czy tez ciało. ta nowa funkcjonalność to przede wszystkim informacje o przeznaczeniu oraz sposobie obsługi tej klasy/interfejsu itd... tak jak to się ma do tabeli w bazie danych; rodzaj kodowania czy silnik w żaden sposób nie ingerują w sama tabele (mam na myśli to ze nie zmieniają już istniejące dane) ale pomocne są w sytuacji gdy te dane muszą być obsłużone.

Osobiście uważam ze metaprogramowanie (dodawanie metadanych do obiektów języka) nie jest osiągalna w 100% tak jak to ma miejsce w językach które maja ta charakterystykę wbudowana w siebie. Przykładem którym się posłużę tutaj jako język obsługujący metadane jest C#. Tam metadane są ucieleśniane poprzez Atrybuty. Atrybuty w języku C# są to klasy którymi można oznaczyć inne klasy i tak naprawdę one są czytane tylko w przypadku kiedy oznaczane klasy sa czytane przez inna część systemu. W większości przypadków jest tak ze te atrybuty oznaczają takie rzeczy jak czy dana klasa jest serializowalna itd...

Dam może obszerniejszy przykład stosowania atrybutów w C# i na tym przykładzie pokaże czemu w PHP jest to nieosiągalne. Tworząc nowy web service w C# (WCF) robimy tak:

Kod
[ServiceContract(
     Name = "CalculatorService",
     Namespace = "http://microsoft.wcf.documentation",
     CallbackContract = typeof(IHelloCallbackContract),
     SessionMode = SessionMode.Required
   )]
     public interface ICalculator
     {
        
         [OperationContractAttribute(IsOneWay=true)]
         void Add(double n1, double n2);
         [OperationContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
         double Subtract(double n1, double n2);
         [OperationContract]
         double Multiply(double n1, double n2);
         [OperationContract]
         double Divide(double n1, double n2);
     }

     public class CalculatorService : ICalculator
     {
         public void Add(double n1, double n2)
         {
             double result = n1 + n2;
             Console.WriteLine("Received Add({0},{1})", n1, n2);
             Console.WriteLine("Return: {0}", result);
         }

         public double Subtract(double n1, double n2)
         {
             double result = n1 - n2;
             Console.WriteLine("Received Subtract({0},{1})", n1, n2);
             Console.WriteLine("Return: {0}", result);
             return result;
         }

         public double Multiply(double n1, double n2)
         {
             double result = n1 * n2;
             Console.WriteLine("Received Multiply({0},{1})", n1, n2);
             Console.WriteLine("Return: {0}", result);
             return result;
         }

         public double Divide(double n1, double n2)
         {
             double result = n1 / n2;
             Console.WriteLine("Received Divide({0},{1})", n1, n2);
             Console.WriteLine("Return: {0}", result);
             return result;
         }
     }


Jak widzimy w tym przykładzie, ta klasa działa w 100% bez załączonych atrybutów (to co jest miedzy [ ]) ale te dodatkowe dane pozwalają na wygenerowanie WSDL tej usługi oraz pozwala usługom hostingowym na doczytanie się dodatkowych informacji niezbędnych do eksponowania tej klasy jako usługę. (jakbym usuną jakiś atrybut OperationContract z powiedzmy metody "multiply" to hostowana usługa by była o ta jedna operacje mniejsza).

To co w php nie jest osiągalne to jest parsowanie tych komentarzy i przekładanie ich na już utworzone obiekty/enumeracje (php nie zna enumeracji tongue.gif ). Aby moc takowa funkcjonalność zaimplementować w PHP trzeba by było zrobić coś co by parsowało te komentarze i moglo to przekładać na "żywe" obiekty z kodu takie jak klasy, enumeracje itd...
mam na myśli obsługę coś w stylu:
Kod
CallbackContract = typeof(IHelloCallbackContract),
SessionMode = SessionMode.Required


bo to:
Kod
Name = "CalculatorService",
Namespace = "http://microsoft.wcf.documentation"

jest jak najbardziej osiagalne w PHP.

Trochę się rozpisałem tak może i bez sensu bo to wszystko jest w necie, ale liczę na to ze ktoś skomentuje to co napisałem i wywiąże sie z tego ciekawa dyskusja smile.gif

Czekam i Pozdrawiam smile.gif

Napisany przez: szopen 29.08.2008, 17:47:44

Cytat(nasty @ 9.08.2008, 23:48:45 ) *
Z tego co zauważyłem, nie do końca wszyscy się zgadzają na temat tego co to jest meta-programowanie. Zacznę możne, wiec od przedstawienia mojego rozumowania tego terminu.
(...)
(bo nie spotkałem się z pojęciem metaprogramowania w przypadku programowania strukturalnego)

http://wazniak.mimuw.edu.pl/index.php?title=Zaawansowane_CPP/Wyk%C5%82ad_8:_Metaprogramowanie -- C++ ale jak najbardziej strukturalnie. Nawet w takim języku (deklaratywnym) jak SQL można używac metaprogramowania, np. łącząc procedury składowane i Dynamic SQL (pierwszy z brzegu przykład: databasejournal/3657506). I nie jest to to samo, co dane (metadane) opisujące tą procedurę składowaną.
Cytat(nasty @ 9.08.2008, 23:48:45 ) *
jest to dodawanie nowej funkcjonalności, badz tez "wstrzykiwania" jej do już istniejącego kodu bez ingerencji w sama jego strukturę czy tez ciało. ta nowa funkcjonalność to przede wszystkim informacje o przeznaczeniu oraz sposobie obsługi tej klasy/interfejsu itd... tak jak to się ma do tabeli w bazie danych; rodzaj kodowania czy silnik w żaden sposób nie ingerują w sama tabele (mam na myśli to ze nie zmieniają już istniejące dane) ale pomocne są w sytuacji gdy te dane muszą być obsłużone.

Nie do końca się zgodzę. Skoro metadane to sa "dane opisujące dane" to analogicznie metaprogramowanie powinno byćrozumiane jako "kod (a nie dane!) opisujący (tworzący) kod". Tak samo jak jest logika i metalogika.
Cytat(nasty @ 9.08.2008, 23:48:45 ) *
Osobiście uważam ze metaprogramowanie (dodawanie metadanych do obiektów języka)

Właśnie -- czy dodawanie danych (metadanych?) do kodu można nazwać metaprogramowaniem? IMHO -- nie, metaprogramowanie to jest coś więcej smile.gif
Cytat(nasty @ 9.08.2008, 23:48:45 ) *
nie jest osiągalna w 100% tak jak to ma miejsce w językach które maja ta charakterystykę wbudowana w siebie. Przykładem którym się posłużę tutaj jako język obsługujący metadane jest C#. Tam metadane są ucieleśniane poprzez Atrybuty.

C++ nie ma wbudowanej obsługi metaprogramowania (w moim rozumieniu) a całkiem dobrze sobie z tym radzi. Jeśli zaś chodzi o atrybuty... zawsze można je emulować za pomocą jakiegoś preprocesora. Tak to jest robione w samym PHP, przy pisaniu rozszerzeń.
Cytat(nasty @ 9.08.2008, 23:48:45 ) *
Dam może obszerniejszy przykład stosowania atrybutów w C# i na tym przykładzie pokaże czemu w PHP jest to nieosiągalne. Tworząc nowy web service w C# (WCF) robimy tak:

Przepraszam za mały offtop, ale zawsze mnieśmieszyły te trzyliterowe, dotnetowe akronimy. WPF, WCF, WGF... szkoda, że nie ma WTF (i wcale nie chodzi mi tu o Wielkie Twierdzenie Fermata) winksmiley.jpg

Apropos kodu wklejonego przez wrzasq... nie wiem jak wydajnościowo, ale może tak lepiej by było?
  1. <?php
  2.  $dynamicPHP = '';
  3.  for ($i = 0; $i<100; ++$i)
  4.  {
  5. $dynamicPHP .= "echo \"Właśnie wypisuję $i\n\";\n";
  6.  }
  7.  http://www.php.net/eval($dynamicPHP);
  8. ?>


Pozdrawiam smile.gif

Napisany przez: MajareQ 14.10.2008, 21:07:50

Przepraszam, że nie przeczytałem wszystkiego, ale ilość tekstu mnie po prostu odstraszyła smile.gif

Proszę o skorygowanie mojego rozumowania...

Jeśli dobrze zrozumiałem to metaprogramowanie zachodzi wtedy, kiedy generuję treść i edytuję inną w tym samym skrypcie?

Coś zbyt banalne jak dla mnie.

Napisany przez: Sedziwoj 15.10.2008, 00:05:17

@MajareQ
Skoro wszytko jest tak proste dla Ciebie, to przeczytaj temat, to aż jedna strona.

Napisany przez: MajareQ 15.10.2008, 10:38:49

Sedziwoj, nie zrozumiałeś chyba mojej prośby.

Prosiłem tylko o odpowiedzenia na pytanie.
Myślę, że to dla średnio wykształconego programisty nie jest trudne, nieprawdaż?

Napisany przez: Kocurro 15.10.2008, 14:06:46

Z tego co rozumie to metaprogramowanie to pisanie programów poprzez programy. Więc każdy język skryptowy jest metaprogramowalny, java jest metaprogramowalna a także C# jest metaprowalny ... i pewnie wiele innych.

Nie rozumiem natomiast czemu się tak upierać, że PHP nie jest metaprogramowalne.

Zanim zaczniemy się kłócić proszę o podanie jakiś namiarów na prace, które traktują o tym temacie i na podstawie których twierdzicie, że jest tak a nie inaczej.

Sam także postaram się coś znaleźć na ten temat.

pozdrawiam,
Łukasz

Napisany przez: skowron-line 15.10.2008, 15:05:40

@MajareQ tu poczytaj.
http://wazniak.mimuw.edu.pl/index.php?title=Zaawansowane_CPP/Wyk%C5%82ad_8:_Metaprogramowanie
prostym przykładem może być utworzenie pliku zapis do jakiegoś echo i później zaincludowanie tego pliku. ( kiedyś ktoś taki przykład na forum napisał ).

Napisany przez: michalkjp 17.10.2008, 11:14:00

Cytat(LoPMX @ 24.06.2008, 21:06:48 ) *
Prawda jest taka,

Ktoś kiedyś powiedział, że prawda jest jak du%^ - każdy ma własną winksmiley.jpg

Cytat(LoPMX @ 24.06.2008, 21:06:48 ) *
ze jest to czyste naciaganie, by nadarzac za trendem.

PHP od srodka jest kiepskim jezykiem, balaganiarskim. Ale skoro uwazasz, ze chcesz uzywac tak ubogiego i malo elastycznego API to... powodzenia.

Ktoś kiedyś powiedział, że złej baletnicy przeszkadza rąbek u spódnicy.

Bardzo lubię te dyskusje o wyższości jednego języka nad drugim. Weźmy na przykład takie C – jest to całkiem archaiczny język średniego poziomu, który od dawna nie nadąża za trendami. I co z tego? Ludzie w nim piszą systemy operacyjne.

Kiedyś Rafał Wysocki (linuksowy hacker) powiedział mi jak patrzy na te wszystkie języki (z pozycji cholernie dobrego programisty) "ważne jest to, żeby dało się zapisać algorytm". Reszta jest mało ważna winksmiley.jpg

Życzę miłego rozkminiania ezoterycznych problemów wyższości jednego języka nad drugim.

Napisany przez: Sedziwoj 17.10.2008, 12:30:47

Cytat(michalkjp @ 17.10.2008, 12:14:00 ) *
Kiedyś Rafał Wysocki (linuksowy hacker) powiedział mi jak patrzy na te wszystkie języki (z pozycji cholernie dobrego programisty) "ważne jest to, żeby dało się zapisać algorytm". Reszta jest mało ważna winksmiley.jpg

A ja powiem cholernie ograniczony punkt widzenia, bo język jest dobry do tego do czego został stworzony, nikt normalny nie będzie pisał OS w Java, bo jest do czegoś innego, nit nie napisze całej aplikacji w C, bo to też nie o to chodzi (pomijam aplikacje specjalistyczne, gdzie wydajność to priorytet), Java i podejście obiektowe spełnia swoje zastosowanie jako możliwość szybszego tworzenia aplikacji, dla których wydajność nie jest priorytetem. Metaprogramowanie też sprawdzi się w pewnych miejscach, ale nie wszędzie. Języki się pojawiają, zmieniają po to aby sprawdzić różne możliwości zapisu programów i te lepiej spełniające swoje założenia przechodzą dalej. (np. pojawienie się Generics w Java, bo były bardzo użyteczne)

Napisany przez: Cysiaczek 17.10.2008, 13:30:03

@ 2 powyższe posty - Proszę nie robić offtopów

Napisany przez: michalkjp 17.10.2008, 14:16:15

@Cysiaczek

Ok, już nie będę (nie zwracaj uwagi na 3 poniższe zdania winksmiley.jpg)

@Systemy operacyjne w Javie

Takie systemy istnieją, działają i wcale nie piszą ich nienormalni ludzie. Oczywiście należy się zgodzić z tym, że jedne języki są lepsze do określonych zastosowań inne gorsze, ale nie należy wprowadzać żadnego językowego faszyzmu. Przetwarzanie formularza na stronie da się zrobić nawet z poziomu Pascala – wystarczy tylko umieć.

// Widzę że nie bardzo do Ciebie dociera to co się piszę. Może ostrzeżenie Cię czegoś nauczy.
// ~webdice

Napisany przez: pawkow 20.10.2008, 23:05:13

PHP Jak najbardziej pozwala na metaprogramowanie, podobnie jak każdy inny język który nie wymaga kompilacji plików źródłowych do poprawnego ich działania (tak sądzę, nie znam wszystkich tych języków).

Za "program" w PHP można uznać zbiór skryptów stanowiących jedną aplikację, która może (o czym wszyscy doskonale wiemy) zamieniać sama swoje pliki źródłowe. Często spotyka się aplikacje które przechowują dane (jak np. ustawienia) w swoich plikach źródłowych, będących podstawowymi plikami aplikacji. Aplikacje te umożliwiają zamianę tych danych w trakcie działania aplikacji (może się to odbywać bez ingerencji programisty).

Późno już jest więc może nie do końca zrozumiałem definicję metaprogramowania, pisze co myślę.

Napisany przez: Sh4dow 21.10.2008, 14:38:22

Nie wiem czy dobrze zrozumiałem dość obszerny post nasty to to co jest miedzy nawiasami [] jest tylko opisem komentarzem. Na podstawie którego jest powiedzmy (tak jak w przykladzie powiedział) generowany plik WSDL czyli to powinno być zaliczane do meta programowania jeśli ja na postawie kawałka kodu oraz jego komentarza wygeneruje plik wymagany do jakiegoś działania, w tym wypadku tekże niech to będzie WSDL

  1. <?php
  2.  
  3. class Obj {
  4.    /**
  5.      *
  6.      * @return int
  7.      */
  8.    public function pobierzLicznik() {
  9.       //jakis tam kod
  10.   }
  11. }
  12. ?>


Na podstawie komentarza, a da sie go parsować i odczytać, mozna wygenerowac wsdl ktory bedzie opisywac metode pobierzLicznik i automatycznie opisywać ze zwraca liczbę całkowitą. Czy to nie bylo by już meta programowanie ? Jeśli dobrze zrozumiałem.

Nierozumiem dlaczego by to nazywać trendem. Co, jest to modne ? Tak jak kiedyś posiadanie swojego frameworka czy CMS'a ? To poprostu moim zdaniem czasami jest dość wygodne przy odpowiednim nakładzie pracy ale zeby nazywać to trendem.

Pozdrawiam.

Napisany przez: Spawnm 21.10.2008, 14:48:24

http://pl.wikipedia.org/wiki/Metaprogramowanie
Metaprogramowanie - jest techniką która umożliwia programom tworzenie lub modyfikację kodu innych programów (lub ich samych).


Tak więc oczywistym jest że PHP daj takie możliwości , np: tworzenie kodu JavaScript smile.gif
pobieramy nazwy grafik z folderu i dajemy je do pętli generującej zmienne js dla galerii js.

Napisany przez: Sedziwoj 21.10.2008, 15:52:34

@Spawnm
Nie do końca o ten sens chodzi w tym temacie, chodzi o generowanie kody PHP przez PHP na podstawie jakiś metadanych. (taki ja sens tego widzę) Czyli robienie wiele nie robiąc dużo.

Napisany przez: bigZbig 21.10.2008, 17:43:02

Jeśli pod pojęciem metaprogramowanie rozumiemy "uzupełnianie" lub "wzbogacanie" kodu aplikacji już podczas wykonywania tego kodu to w php jest to jaknajbardziej możliwe. Służą do tego takie funkcje jak np. [b]create_function[/b] czy eval, a także Reflection API. Z mojego punktu widzenia metody magiczne takie jak __get, __set czy __call to też metaprogramowanie gdyż umożliwiają obsłużenie przez programistę przypadków, których nie może on z góry przewidzeć (uzależnionych np. od struktury danych), lub ma zwyczajnie ochotę na implementację mechanizmów uniwersalnych.

Rezultaty tego metaprogramowania mogą zostać "utracone" w chwili wykonania kodu lub też zapisane do późniejszego wykożystania. Przy pomocy PHP możemy wygenerować nowe fragmenty kodu a nawet przedefiniować już zdefiniowane przez nas klasy czy funkcje. Dla mnie jest to już metaprogramowanie. Możemy dyskutować, który język jest bardziej predystynowany do tego aby nazywać go królem metaprogramowania, ale chyba nie o ranking w tym wątku chodzi.

Napisany przez: bregovic 3.11.2008, 00:52:46

Jako ciekawostka, dzięki funkcjom lambda, od PHP5.3 będzie możliwe rozszerzanie klas o nowe metody - na żywo.

  1. <?php
  2. class Object {
  3.    private http://www.php.net/static $methods = http://www.php.net/array();
  4.  
  5.    public http://www.php.net/static function extend($name, $method) {
  6.        if (is_callable($method)) {
  7.            self::$methods[$name] = $method;
  8.        }
  9.    }
  10.  
  11.    public function __call($method, $arguments) {
  12.        if (http://www.php.net/isset(self::$methods[$method])) {
  13.            http://www.php.net/array_unshift($arguments, $this);
  14.            return call_user_func_array(self::$methods[$method], $arguments);
  15.        } else {
  16.            throw new Exception('Unknown method '.$method.' called.');
  17.        }
  18.    }
  19.  
  20.    public http://www.php.net/static function __callStatic($method, $arguments) {
  21.        if (http://www.php.net/isset(self::$methods[$method])) {
  22.            http://www.php.net/array_unshift($arguments, get_called_class());
  23.            return call_user_func_array(self::$methods[$method], $arguments);
  24.        } else {
  25.            throw new Exception('Unknown method '.$method.' called.');
  26.        }
  27.    }
  28. }
  29. ?>

Dzięki podobnemu rozwiązaniu zaimplementowałem lazy-loading danych z DB do moich modeli (a zwłaszcza kolekcji modeli). Oprócz tego, dzięki lambdom możliwe jest np napisanie metody 'each' dla kolekcji. Powyższą klasę można wykorzystać np tak:
  1. <?php
  2. class Foo extends Object {
  3. }
  4.  
  5. $method = function($one, $two) {
  6.    return $one + $two;
  7. };
  8.  
  9. Foo::extend('add', $method);
  10.  
  11. http://www.php.net/echo Foo::add(2, 2);
  12. // 4
  13. ?>

Napisany przez: tuner 3.11.2008, 12:32:38

Cytat(bregovic @ 2.11.2008, 23:52:46 ) *
(...) Dzięki podobnemu rozwiązaniu zaimplementowałem lazy-loading danych z DB do moich modeli (a zwłaszcza kolekcji modeli). Oprócz tego, dzięki lambdom możliwe jest np napisanie metody 'each' dla kolekcji. (...)
Mógłbyś się podzielić kawałkami kodu przykładów? Zainteresowała mnie ta część postu i chętnie przeczytam więcej.

EDIT:
Zainteresowanych odsyłam do klasy Collection autorstwa bregovica:
http://github.com/brego/prank/tree/master/core/collection.php

Napisany przez: bigZbig 19.02.2009, 15:34:40

Wzbogacanie klas o dodatkowe metody jest od dawna możliwe i bez funkcji lambda http://www.garfieldtech.com/blog/php-magic-call

Napisany przez: erix 11.04.2009, 19:42:50

Cytat
Nie moge sie doczekac PHP 5.3 i pierwszego projektu ktory skusi sie na uzycie namespace

Nie skuszą się. Był na hostingach ongiś wielki ból, aby zainstalowano PHP5, niektóre są bardzo ospałe, jeśli chodzi i update bieżących wersji PHP, to myślisz, że ktoś sobie pozwoli na problemy wywołane nowymi funkcjami? Za rok od wprowadzenia przestrzeni nazw, to rozumiem, ale na pewno nie tak prędko.

Cytat
Co mi po tym ze stworze alias do danego namespace'a czy klasy? Wolalbym sobie zaimportowac namespace tak jak ma to miejsce w C++ (using namespace My\Full;) ...

Z tego, co mi wiadomo, to i tak była gorąca dyskusja właśnie w ekipie tworzącej interpreter, jakiego operatora używać do deklarowania przestrzeni nazw. tongue.gif Już nie pamiętam, na czym stanęło.

Cytat
Swoja droga... ciekaw jestem czego jeszcze mozemy sie spodziewac...

W sumie, to naprawdę wszystkiego - np. kiedyś był moduł MySQL zintegrowany, potem poleciał do rozszerzenia i znowu wraca do rdzenia...

Cytat
P.S. Jezeli uwazacie ten watek za ciekawy do dyskusji (zdaje sobie sprawe iz to nie jest raczej wlasciwe miejsce), to prosze o kontakt, zalozenie oddzielnego tematu, albo sam to zrobie i bedziemy mieli okazji do przedyskutowania tego.

Chętnie, ale zobaczymy, czy więcej osób podejmie dyskusje; jestem jak najbardziej "za".

Napisany przez: Morkai 14.04.2009, 21:45:10

Cytat(belliash @ 12.04.2009, 12:33:42 ) *
Pomijam fakt ze namespace musi byc zadeklarowany zaraz na poczatku pliku, gdzie wolalbym najpierw wpisac (...)
Pliki, do których użytkownik ma nie mieć dostępu umieszcza się poza public_html.
Cytat(belliash @ 12.04.2009, 12:33:42 ) *
(...) za akzdym razem trzeba pisac \CORE\[Klasa] albo zaliasowac sobie... use \CORE\[Klasa] as Klasa... jak dla mnie nie porozumienie - jakby nie mozna bylo wpisac np import CORE. Mozna by powiedziec - zmiast deklarowac namespace CORE - kernela wstawic w global scope - nie pomogloby. use \Klasa as Klasa sad.gif czyli dokladnie ten sam problem...
Nawet mając do dyspozycji przestrzenie nazw, nie powinieneś nazywać klas tak samo. Dodawanie as Klasa do use \Klasa jest równoznaczne z samym use \Klasa. Zaliasowanie wszystkich używanych klas pozwala szybciej zorientować się, jakie definiowana klasa ma zależności. Nie trzeba latać po całym pliku.
Z resztą jaki % czasu w porównaniu do napisania całej klasy zajmie Ci wpisanie usingów?
Cytat(belliash @ 12.04.2009, 12:33:42 ) *
Inny przyklad - kod zaczerpniety ze strony IBMa: (...)
Albo piszesz obiektowo albo strukturalnie.

Napisany przez: Morkai 15.04.2009, 12:55:23

Cytat(belliash @ 14.04.2009, 21:16:53 ) *
Wytlumacz mi prosze co ma piernik do wiatraka?

  1. <?php
  2. http://www.php.net/defined(COS) or http://www.php.net/die('nie mozna uruchomic bezposrednio');
  3. ?>


Cytat(belliash @ 14.04.2009, 21:16:53 ) *
Po to sie uzywa namespace aby moc miec kilka kals o tej samej nazwie - jaka mam pewnosc ze nikt nie bedzie chcial polaczyc mojego projektu z innym projektem i ze nie wystapi konflikt nazw?

Po dodaniu przestrzeni nazw, pełna nazwa klasy to namespaceName\ClassName. Po to się dodaje nazwę projektu/firmy do ns, aby takie problemy nie wystąpiły. Jeżeli masz dwie klasy o takiej samej nazwię to znaczy, że robią to samo. Czy jedną z głównych cech OOP przestało być code reuse?

Cytat(belliash @ 14.04.2009, 21:16:53 ) *
I wytlumacz mi o jakie zaleznosci Ci chodzi bo nie bardzo rozumiem...

Zależności pomiędzy klasami. Jeżeli Foo korzysta z Bar i Baz, to od nich zależy.

Co do tego kodu. Nie wiem czy w alpha wyświetlał się ten błąd (może autor miał wyłączone wyświetlanie ostrzeżeń), ale PHP informuje, że trzeba dodać przestrzeń nazw przed wywołaniem funkcji
Cytat(PHP)
Warning: The use statement with non-compound name 'UtilsLeft' has no effect in /home/.../ns.php on line 8

Warning: The use statement with non-compound name 'UtilsRight' has no effect in /home/.../ns.php on line 11
I'm using my left hand!I'm using my right hand!
Fatal error: Call to undefined function whichHand() in /home/morkai/workspace/tests/ns.php on line 9

Tak samo jest w Pythonie. Chociaż Python pozwala na importowanie funkcji trzeba każdą zimportować każdą z osobna (co ma sens). Tobie się nie podoba, że trzeba importować klasy. Co by było jakbyś musiał importować funkcje ^^

Napisany przez: mike 15.04.2009, 13:00:55

Cytat(Morkai @ 15.04.2009, 13:55:23 ) *
Po dodaniu przestrzeni nazw, pełna nazwa klasy to namespaceName\ClassName. Po to się dodaje nazwę projektu/firmy do ns, aby takie problemy nie wystąpiły. Jeżeli masz dwie klasy o takiej samej nazwię to znaczy, że robią to samo. Czy jedną z głównych cech OOP przestało być code reuse?
Ale bzdury. Ale bzdury.
Zasada http://en.wikipedia.org/wiki/Code_reuse nie ma tu najmniejszego znaczenia. Strzelasz bzdurnymi argumentami od czapy w stylu "Jeżeli masz dwie klasy o takiej samej nazwię to znaczy, że robią to samo."

Po to powstały przestrzenie nazw, żeby do nich pakować całe biblioteki czy projekty i nie martwić się, że Ci się, na przykład klasa Parser powtórzy.
Zajrzyj może do innych języków, na przykład do Javy. Dostrzeżesz śmieszność we własnych postach tongue.gif

Napisany przez: erix 15.04.2009, 17:15:39

Cytat
powiedz mi jak na hostingu umiescic cos poza public_html?

Normalnie. Porządny hosting umożliwia Ci zapis plików poza public_html. Jeśli nie, to cóż... winksmiley.jpg Trzeba kombinować z Rewrite.

Napisany przez: bigZbig 15.04.2009, 20:40:31

Prawdą jest, że porządny hosting udostępnia katalog co najmniej o poziom wyżej public_html, ale jeśli nawet tak nie jest to można sobie poradzić używając podkatalogu z odpowiednim .htaccess - em. Pisanie w każdym pliku czegoś na kształt:

  1. <?php
  2. http://www.php.net/defined(COS) or http://www.php.net/die('nie mozna uruchomic bezposrednio');
  3. ?>

jest amatorszczyzną bo.
1. Trzeba pamiętać aby ten wpis znalazł się w każdym pliku.
2. Nie zabezpiecza to bibliotek zewnętrznych gdyż trzeba by dodać podobny wpis do każdego pliku, każdej zewnętrznej biblioteki np. Smarty, htmlpurifier, Swiftt, Zend itd.
3. Użycie plików z takim wpisem w innych projektach wymusza zdefiniowanie odpowiedniej stałej

Oczywiście tematem niniejszego wątku nie jest zabezpieczenie plików tak więc wracając do meritum sprostuję jeszcze, że w Pythonie nie trzeba wymieniać literalnie, każdej funkcji, którą chce się zaimportować, choć uważam to za w sumie dobrą praktykę.

Zgadzam się z moimi przedmówcami, którzy stoją na stanowisku, że ideą przestrzeni nazw jest wyeliminowanie problemów ze zdublowanymi nazwami klas lub funkcji. Programując często zmuszony jesten do tworzenia rozbudowanych nazw klas. Niestety php jak dotąd wymusza nadawanie nazw klasom i funkcją w odniesieniu do całej aplikacji. Stąd przedrostki typu smarty_, Zend_, My_ itp. O ile prostsze byłoby użycie krótkiej nazwy, która w danym kontekście byłaby jednoznaczna. Rozwiązaniem mają być namespace-y. Czytałem dokumentację dotyczącą namespace-ów w php i powiem Wam, że jak na razie to co tam piszą jest mało intuicyjne i nie jestem pewien czy mi się to podoba.

Napisany przez: Nattfarinn 11.05.2009, 16:16:09

Nie chcę specjalne marudzić, ale czy temat nie tyczy się czasem Metaprogramowania a nie zastosowań przestrzeni nazw wraz z rozwiązaniami nowego PHP?

Metaprogramowanie, to... dziwna rzecz. Wydaje mi się, że mniej więcej łapię założenia jakie kierują metaprogramowaniem. Umyka mi za to trochę sens takich rozwiązań... Nie potrafię sobie wyobrazić sytuacji w której użycie metapr. byłoby conajmniej wskazane (i optymalne). Generowanie kodu który w niedalekiej przyszłości miałby zostać wykonany to (wybaczcie, widocznie nie mam aż tak wielkiej wyobraźni) przerost formy nad treścią. Chyba, że ten temat jest czysto teoretyczny i pomija pytanie "po co?" na rzecz "czy da się?" bo nie sądzę, żeby skrypt sam był w stanie uzupełnić sie o newralgiczne elementy. Hmm, ORM?

I tak mnie właśnie coś ruszyło... Czy rozwiązanie Zend Framework odnośnie klas tablic objętych relacją i wywołań właściwie nieistniejących metod finderów podpada pod Metaprogramowanie? Chodzi mi o wywołanie metody:

  1. <?php
  2. $tabela = new MojaTabela();
  3. $wynik = $tabela->findParentImieByNazwisko('Kowalski');
  4. ?>

Napisany przez: metadetron 10.05.2010, 10:47:25

Nie wiem czy to już metaprogramowanie czy tylko generowanie kodu, ale ja używam do tego Apache Velocity, które mi generuje klasy PHP. Skrypt wygląda w uproszczeniu tak:

  1. class virgo${tr.FV($entity.name)} extends JTable {
  2. var $${entity.prefix}_id = null;
  3. #foreach( $property in $entity.properties )
  4. var $${entity.prefix}_${tr.f_v($property.name)} = null;
  5. #end
  6. ...

Wszak każdy projekt jest bardzo podobny - są tabele i kolumny. Żeby nie klepać ciągle tego samego mam program, który mi to pisze za mnie.

Napisany przez: dariuszp 9.09.2010, 23:07:35

Metaprogramowanie. Temat na tyle obszerny i dla mnie mało znany że sam nie wiem czy dobrze go rozumie ale chciał bym o coś zapytać.

Otóż swego czasu poszedłem sobie na spore ułatwienie. Otóż pisałem mappery do dość obszernej bazy danych i miało to troszkę potrwać. Dopóki nie wpadłem na mały pomysł. Otóż dopisałem po prostu kod PHP który zwyczajnie w wypadku braku obiektu danych dla mappera bazy danych łączy się z bazą, pobiera informacje o tabeli do której odnosi się mapper (lub tabel, kwestia co mapper dokładnie robi ale takich co odnoszą się do +1 tabeli mam mało) i... tworzy klasę obiektu danych dla tej tabeli i zapisuje do pliku. Taki plik jest później po prostu includowany przez system.
Podobnie jest z mapperami ale tu zaoszczędza mi to tylko połowę pracy. Bo czasami mapper potrzebuje specyficzną metodę tylko dla siebie. Jednak i tak mam oszczędzone żmudne klepanie.

W każdym razie PHP wychodzi na przeciw naszym potrzebą. Mój system nie tylko potrafi sobie wygenerować obiekt danych jeżeli nikt go nie zapewni na podstawie bazy danych ale tez i na podstawie mappera (który ma bazę translacji gdzie wewnętrzna zmienna bądź tablica ma info co powinno się przyporządkować jakiemu atrybutowi obiektu danych). Osiągnąłem to w dość prosty sposób (choć jak pierwotnie o tym pomyślałem to wydawało mi się to niemożliwe).

Użyłem token_get_all();. Funkcja ta jest w stanie wczytać z pliku kod PHP, rozbić go na czynniki pierwsze i zaserwować nam tablicę. Używając token_name() identyfikuję cyferki na nazwy i łatwo wyłapuje elementy składni. Ich lista znajduje się tutaj: http://www.php.net/manual/en/tokens.php

W skrócie. PHP jest w stanie W PEŁNI zanalizować kod PHP a co dalej zrobicie to Wasza sprawa. Pamiętajcie tylko by zachować to na specjalne przypadki bo nie są to operacje lekkie. Sam umieściłem takie rozwiązanie tylko w paru drobnych miejscach jak właśnie przy mapperach. W razie gdy nie chce mi się tworzyć obiektów danych bądź też po prostu zapomniałem o tym, system sam zaopiekuje się tym problemem jeżeli odnajdzie mappera bądź tabelę w bazie danych.

I taka ciekawostka dla Was. Swego czasu napisałem małe narzędzie które odchudziło mi kod PHP. Powyższym sposobem wyciąłem WSZYSTKIE białe znaki (co najlepsze nie potrzeba wyrażeń regularnych, ciągi znaków w "" i '' są oznaczone w tablicy jako string, reszta jako elementy składni więc nie można wyciąć białych znaków np z komunikatów przypadkiem), komentarze itp. Po instrukcjach wstawiłem spację (żeby nie dostać classDatabase tylko class Database) no i upewniłem się że po -> nie ma spacji ( $obiekt->include() to nie to samo co $obiekt -> include() ) a całą resztę zostawiłem w spokoju. Pozbyłem się też komentarzy.

Wyszło na to że 31% mojego kodu w systemie to spacje, tabulatory i komentarze. Ponieważ rozmiar plików zmniejszył się do 69%. W każdym razie PHP potrafi o siebie zadbać :-)


W każdym razie to pytanie:
Czy gdy system sam się potrafi odchudzić (wywołując sobie odchudzanie na nowych plikach, dorabianie sobie obiektów danych w razie czego itp), uzupełnić itp wg wytycznych (listę tego co usunąć np umieszczam w phpdoc nad metodą która to robi. PHP jest w stanie również dobrać się od tych komentarzy. A ktoś czytając kod klasy jest w stanie powiedzieć co ona wywali. Mało tego, modyfikując komentarz modyfikuje zachowanie klasy.) itp to możemy tutaj mówić o metaprogramowaniu ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)