Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Pro _ PHP preprocessor

Napisany przez: hawk 20.04.2004, 16:13:11

Chodzi mi po głowie taki "preprocesor" albo "kompilator" do php. Hmm, wyobraźcie sobie że macie jakiś obiektowy systemik - powiedzmy kilkanaście klas, w tym interfejsy (PHP5). I chciałoby się wypuszczając oficjalną wersję tego systemiku wrzucić to wszystko do jednego pliku, bo i tak te klasy się nazwajem potrzebują. A interfejsy w ogóle nie są potrzebne - tylko ułatwiają pisanie - i można je całkowicie usunąć.

I uruchamiałoby się taki preprocesor, który mergowałby pliki, usuwał (niepotrzebne już) instrukcje require_once(...) itd. Sprawa nie jest prosta, bo preprocesorowi trzeba jakoś powiedzieć, co ma do czego przerzucić, a co zostawić w spokoju. No i nie może on absolutnie pogubić się i wprowadzać do kodu nowe błędy.

Czy takie coś może istnieje? Czy to jest w ogóle dobry pomysł?

Napisany przez: seaquest 20.04.2004, 17:09:16

IMHO pomysł ciekawy, ale nieopłacalny. Załóżmy, że system składa się z kilkudziesięciu klas, ale przecież nie zawsze wszystkie są potrzebne, czasami nie musisz używać wszystkich klas, a parser to przetwarza (niestety) i tracisz potrzebne sekundy....

Napisany przez: Nalfein][WR 20.04.2004, 18:37:26

Właśnie dlatego ten prekompilator musiałby być konfigurowalny tj. mieć jakiś plik wejściowy z listą klas i na podstawie tych klas załadować wybrane pliki, oczyścić z komentarzy, zbędnych instrukcji wg. gdzieś w ustawieniach wprowadzonych regexów, a następnie scalić generując docelowy plik .php biblioteki. Ale jest też druga strona medalu - w plikach, które używały dotychczas klas includując pojedyncze pliki także należałoby pozmieniać wywołania, albo w jakiś sposób powiązać nazwę klasy z nazwą biblioteki, ale to wymaga ingerowania w __autoload bądź wyprowadzenia dodatkowego obiektu do ładowania klas.

Napisany przez: hawk 20.04.2004, 18:37:41

Hmm, ja zakładam że:
1) preprocesor odpalam sobie tylko raz, u siebie, zanim wypuszczę na zewnątrz gotową wersję (a wersja z wieloma plikami mogłaby nazywać się "debug")
2) wiem które klasy są potrzebne zawsze a które od czasu do czasu, i łączę ze sobą tylko te, które i tak będą musiały być zawsze wczytywane

To powoduje, że trzeba jakoś poinformować parser, co wolno mu mergować sad.gif

Napisany przez: Nalfein][WR 20.04.2004, 20:12:31

No jakoś trzeba. Ja wykorzystuję swój generator kodu wbudowany we framework, który odczytuje pliczek XML-owy ze "składnikami" i robi na jego podstawie gotowy "posiłek" dla interpretera w postaci pliczku php. Zmiana przepisu pociąga za sobą rekompilację. Użytkownik dostaje samo menu - klasy w osobnych plikach, ale przy pierwszym odpaleniu zostanie zrobiony cache.

U mnie pliczek źródłowy wygląda tak:

  1. <?codegen use="php-cache"?>
  2. <cache>
  3.  <part>
  4.        <source path="./core/Object.php" />
  5.      <class>Object</class>
  6.  </part>
  7.  <part>
  8.      <source path="./core/Worker.php" />
  9.      <class>Worker</class>
  10.  </part>
  11.  <part>
  12.        <source path="./core/Component.php" />
  13.      <class>Component</class>
  14.  </part>
  15.  <part>
  16.        <source path="./util/List.php" />
  17.      <class>List</class>
  18.  </part>
  19.  <part>
  20.        <source path="./util/Map.php" />
  21.      <class>Map</class>
  22.  </part>
  23.  <part>
  24.        <source path="./application/Application.php" />
  25.      <class>Application</class>
  26.  </part>
  27.  <part>
  28.      <source path="./application/CustomApplication.php" />
  29.      <class>CustomApplication</class>
  30.  </part>
  31.  <part>
  32.        <source path="./application/PaladineFramework.php" />
  33.      <class>PaladineFramework</class>
  34.  </part>
  35. </cache>


Procesor wyciąga klasy po regexach. Bardzo proste, a spełnia swoje zadanie.

Napisany przez: Nalfein][WR 20.04.2004, 20:17:31

serafin - to zarzuć może nazwą...

Argument co do czasu wykonywania jest chybiony. Operacja przecież będzie wykonywana tylko przy zmianach projektu.

Napisany przez: e-Gandalf 20.04.2004, 21:31:22

Hawk: jej! :DDDDD Wiem, ze to niewiarygodne, ale myslalem swego czasu o czyms identycznym. Dokladnie o "kompilacji"/"kompresji".
Zalety? Liczne.

1) Mieszacz kodu. Uzyskujemy efekt zblizony do kompilacji i uwierzcie - wlasciwie niemozliwy do rozkodowania (przy uzyciu rozsadnych srodkow)
2) Zmniejszenie includow - jak wszyscy wiemy include i require to wlasciwie najwezsze gardla kazdej aplikacji
3) usuniecie komentarzy w wersji "produkcyjnej", a jak wiemy, dobrze udokumentowany plik potrafi zawierac wiecej komentarzy niz kodu smile.gif

Ja za, ale moze po Tothu smile.gif

Napisany przez: hawk 20.04.2004, 21:56:53

Taki preprocesor może bardzo dużo zrobić minimalnym kosztem, naprawdę...
1) Wycinanie komentarzy - zero regexpów, wbudowany tokenizer, idzie jak burza
2) wycinanie białych spacji - w PHP5 jest do tego jedna funkcja
itd...

@Nalfein: czy twój generator kodu potrafi wyciąć niepotrzebne już require_once i inne takie? Bo generalnie to co napisałeś to mniej więcej to o co mi chodzi - podaje się w jakimś pliku, jakie pliki ma sparsować, i wypluwa jeden scalony plik.

Ja bym jeszcze bardzo chciał wywalić z pliku "produkcyjnego" interfejsy, bo prawie zawsze nie są one potrzebne do poprawnej interpretacji (chyba że ktoś używa instanceof, ale ja zamiast tego zawsze class type hints w definicji metody, i tutaj można je wyciąć).

@serafin:
A da sie to zrobić jakimś preprocesorem C? awkiem? nie wiem... Takie coś musiałoby rozumieć chociaż trochę kod php.

Napisany przez: wojtek 21.04.2004, 14:22:22

To ja jeszcze wtrace swoje dwa grosze - nie wiem czy znacie moze taka aplikacje jak POBS http://pobs.mywalhalla.net/. Najprostsza rzecza jaka robi to wlasnie usuwanie bialych znakow, lecz zmienia ona takze nazwy zmiennych, funkcji itd na nieczytelne. Jest to dosyc skomplikowane zadanie, autorzy sami pisza ze po zastosowaniu skryptu trzeba naniesc kilka zmian czy poprawek. Napisanie takiego pre-processora byloby dosyc trudne i trzebaby przewidziec mnostwo sytuacji - jesli jednak udaloby Ci sie cos takiego napisac, mysle ze byloby to bardzo przydatne narzedzie.

Napisany przez: e-Gandalf 21.04.2004, 16:24:34

Cytat
Byc moze nie zrozumialem troche idei... Jesli ma to wygladac w ten sposob, ze wg listy plik scala je w calosc to jest to chybiony pomysl. Czemu ? Skad "preprocessor" bedzie wiedzial ze includujac plik akcji ma go pominac (bo jest przeciez zmieniany dynamicznie) czy tez tworzyc bedzie xxxx scalonych plikow dla kazdej z akcji ? Myslicie ze taki "inteligentny" parser da sie napisac ?


Tak. Zauwaz, ze o ile faktycznie czesc rzeczy musi pozostac jako "moduly" to czesc moze zostac wlaczona. W mnoim przekonaniu, dobry programista piszac obiektowa aplikacje zazwyczaj tworzy po jednym pliku na kazda klase. Jesli zatem jadro sklada sie z 10 klas (baza danych, uprawnienia, szablony, cache, costam) i kilku plikow glownych (index.php, main_lib.php) - do tego kilku klas prymitywnych, abstrakcyjnych i kilku interfejsow to w wersji produkcyjnej mozna by to zlaczyc w jeden plik, oszczedzajac kilkunasty include/require (i na dodatek wywalajac interfejsy/klasy abstrakcyjne). Oczywiscie pewnei trzeba by jakos zaznaczyc "twarde" includy, ktore maja zostac includami, ale mysle, ze na koncu zamiast 100 plikow mozna by miec plik index.php (jadro) i kilka-kilkanascie modulow ladowanych w zaleznosci od potrzeb.

Napisany przez: e-Gandalf 21.04.2004, 17:50:17

No, pisalem przeciez:

"Oczywiscie pewnei trzeba by jakos zaznaczyc "twarde" includy, ktore maja zostac includami" smile.gif

Napisany przez: Nalfein][WR 21.04.2004, 19:22:01

hawk: nie, na odwrót. Zamiast usuwać require_once wycina klasy o podanych identyfikatorach z plików źródłowych i umieszcza w wynikowym. Jeśli tamte klasy potrzebują innych to należy je dołączyć manualnie w pliku konfiguracyjnym.

Napisany przez: hawk 21.04.2004, 19:32:52

Cytat
To ja jeszcze wtrace swoje dwa grosze - nie wiem czy znacie moze taka aplikacje jak POBS http://pobs.mywalhalla.net/. Najprostsza rzecza jaka robi to wlasnie usuwanie bialych znakow, lecz zmienia ona takze nazwy zmiennych, funkcji itd na nieczytelne.

POBS jest ciekawą aplikacją, i nie znałem wcześniej :wink: . Ale tak na oko widać, że ma on poważne wady, spowodowane nie brakiem umiejętności twórcy, tylko tym, że POBS powstał, gdy php nie dysponował funkcjonalnością znakomicie ułatwiającą tego typu zadania.

Przykłady, wzięte ze strony programu:
- POBS ma drobne problemy z wycinaniem komentarzy, a tokenizer czyni to dziecinnie prostym
- POBS myli czasami nazwy stałych z tagami HTML, a tokenizer nie ma z tym problemu
- POBS ma duże trudności ze zmiennymi typu $$nazwa, a za pomocą tokenizera można je łatwo rozpoznać
- POBS, wycinając spacje, potrafi popsuć kod HTML, a PHP5 (jak zakładam) zrobi to dobrze

O obsuscatorze nie myślałem, ale może kiedyś...

Napisany przez: enceladus 21.04.2004, 19:57:09

Dyskusja przybrała taką formę, że mogę śmiało stwierdzić że pewne postawione tu wymagania spełnia MMCache: kompiluje plik tekstowy php do bytecodu a podczas tego procesu kod jest oczyszczany. Jedynie nie parsuje include-ów.

Update: Oczywiście wymaga ingerencji w apache'a

Napisany przez: hawk 21.04.2004, 23:07:46

@Nalfein:
Aaaaaa, sprytne smile.gif . Chociaż wtedy jest pewne ryzyko, że "zgubi się" jakieś define(...) i takie, umieszczone poza klasą. Ale w PHP5, mając nowe słowo kluczowe const, stosuję raczej zasadę "jeden plik = jednak klasa i nic poza klasą".

@enceladus:
MMCache też robi z tego tyle plików, ile było na początku. Chociaż nie znam zasad działania na tyle dobrze, aby stwierdzić, czy weźmie pliki z bytecodem z dysku, czy będzie je trzymał w pamięci. Ciekawe, jaka dla MMCache jest różnica pomiędzy 10 plikami, a 1 plikiem powstałym ze sklejenia tamtych. W sensie szybkości, oczywiście.

Napisany przez: LoPMX 10.07.2004, 20:48:52

Wydaje mi sie, ze lepie byloy taki preprocesor wykorzystac do wydawania release aplikacji. powiedzmy wersja release i debug. wypuszczajac wersje release, preprocesor: obcina komentarze, dalej usuwa wszystko np. pomeidzy #ifdef DEBUG / #endif. Powiedzmy w tym bloku bylyby jakies dodatkowe logi itd potrzebne programiscie a nie w koncowym produkcie.

Napisany przez: Jabol 10.07.2004, 21:05:38

a może coś jak w C? Można by było nawet # zostawić jako rozpoznawacz komend preprocesora

Kod
<?php
#ifdef VERSJA_FINALNA
#include "klasa.class.php"
#else
require_once "klasa.interfejs.php";
require_once "klasa.class.php";
#endif // VERSJA_FINALNA
?>
i potem tylko
$ convert --in plik.php --out finalna.php -D VERSJA_FINALNA
Albo napisać język do opisu różnych akcji. Coś np. jak
Kod
outfile $klasa "finalna/$1.class.php"
from "klasa.class.php" import * without [includes('*.interface.*')] to $klasa('klasa')
Albo coś w tym stylu i potem tylko interpreter.

Drugi sposób ma tą wadę, że trzeba by było napisać jeszcze conajmniej podstawowy parser php.

Napisany przez: bela_666 28.03.2005, 02:45:39

Stary topic, ale co tam, nie będę nowego zakładać :]

Co sądzicie o czymś takim ? :]

  1. <?php
  2. function dump($dump) {
  3. http://www.php.net/print('<pre>');
  4. http://www.php.net/var_dump($dump);
  5. http://www.php.net/print('</pre>');
  6. }
  7.  
  8. $files = http://www.php.net/array(
  9.  'dirs' => http://www.php.net/array(''),
  10.  'disabled_dirs' => http://www.php.net/array(''),
  11.  'files' => http://www.php.net/array(''),
  12.  'disabled_files' => http://www.php.net/array(''),
  13. );
  14. //dump($files);
  15.  
  16. function getFiles($dir) {
  17. $aFiles = http://www.php.net/array();
  18. foreach($dir as $d) {
  19. $rd = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $d ), true );
  20. foreach ($rd as $file) {
  21. if(!$file->isDir() && http://www.php.net/end(http://www.php.net/explode('.', $file)) == &#092;"php\") {
  22. $aFiles[] = $file->getPathname();
  23. }
  24. }
  25. }
  26. return $aFiles;
  27. }
  28.  
  29. $rf = http://www.php.net/array_diff(getFiles($files['dirs']), getFiles($files['disabled_dirs']));
  30. $rf = http://www.php.net/array_merge($rf, $files['files']);
  31. $rf = http://www.php.net/array_merge(http://www.php.net/array_diff($rf, $files['disabled_files']));
  32. //dump($rf);
  33.  
  34. $bigFile = null;
  35. foreach($rf as $file) {
  36. $buff = php_strip_whitespace($file);
  37. // highlight_string($buff);
  38. $buff = http://www.php.net/preg_replace( http://www.php.net/array('/^(<?php|<?)/', '/?>$/'), array('', ''), $buff);
  39. //dump($buff);
  40. $bigFile .= $buff;
  41.  
  42. }
  43. $bigFile = '<?php '. $bigFile . ' ?>';
  44. //highlight_string($bigFile);
  45. file_put_contents('merged.php', $bigFile);
  46. ?>


Konfiguracja poprzez tablice $files

Napisany przez: hawk 29.03.2005, 15:20:10

Fajny przykład, i dobrze pasuje do dyskutowanego ostatnio autoloadera winksmiley.jpg. Ja bym z tego oczywiście zrobił klasę. I zrobiłbym system pluginów do tej klasy, pobierających tekst pliku i zwracających przetworzony tekst pliku. Np. plugin usuwający komentarze, wycinający whitespace, itd. I takie pluginy można łączyć w łańcuszek - co po kolei ma być zrobione.

Albo inny pomysł - łańcuch przetwarzania powinien mieć postać: input -> processing -> output. Tzn. niech będzie interfejs odpowiedzialny za dostarczanie contentu - np. pobierając z pliku, pobierając z listy plików, itd. Drugi interfejs/klasa to główne przetwarzanie i obróbka zagregowanego contentu. A na koniec interfejs zapisujący wynik obróbki. Taki pipeline pozwala na elastyczne dopasowywanie do potrzeb i dopisywanie nowej funkcjonalności.

Najlepiej byłoby opracować coś takiego i wydać razem z autoloaderem...

edit: Coraz bardziej podoba mi się pipeline. Można nawet pójść trochę w stronę Cocoona: zrobić sobie drzewko przetwarzania, gdzie na wejściu (liść) jest input, na wyjściu (korzeń) output, a w środku cokolwiek - agregacja, filtrowanie, wycinanie komentarzy, itd.

Napisany przez: bela_666 10.04.2005, 01:01:57

Cytat(hawk @ 2005-03-29 15:20:10)
Fajny przykład, i dobrze pasuje do dyskutowanego ostatnio autoloadera winksmiley.jpg. Ja bym z tego oczywiście zrobił klasę. I zrobiłbym system pluginów do tej klasy, pobierających tekst pliku i zwracających przetworzony tekst pliku. Np. plugin usuwający komentarze, wycinający whitespace, itd. I takie pluginy można łączyć w łańcuszek - co po kolei ma być zrobione.

No ba, już jest gotowe winksmiley.jpg
  1. <?php
  2. http://www.php.net/error_reporting(E_ALL);
  3. class PreProcessor {
  4. private $plugins;
  5. private $config;
  6. private $fileContent;
  7. private $files;
  8. public function __construct() {
  9. }
  10.  
  11. public function start () {
  12. $this->files = $this->getF($this->config);
  13. $this->loadFiles();
  14. $this->processPlugins();
  15. }
  16.  
  17. private function getFiles($dir) {
  18. $aFiles = http://www.php.net/array();
  19. foreach($dir as $d) {
  20. $rd = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $d ), true );
  21. foreach ($rd as $file) {
  22. if(!$file->isDir() && http://www.php.net/end(http://www.php.net/explode('.', $file)) == &#092;"php\") {
  23. $aFiles[] = $file->getPathname();
  24. }
  25. }
  26. }
  27. return $aFiles;
  28. }
  29.  
  30. public function setConfig($aConfig) {
  31. $this->config = $aConfig;
  32. }
  33.  
  34. public function getConfig () {
  35. return $this->config;
  36. }
  37.  
  38. public function setPlugins($aPlugins) {
  39. $this->plugins = $aPlugins;
  40. }
  41.  
  42. public function getPlugins () {
  43. return $this->plugins;
  44. }
  45.  
  46. private function getF($aF) {
  47. $rf = http://www.php.net/array_diff($this->getFiles($this->config['dirs']), $this->getFiles($this->config['disabled_dirs']));
  48. $rf = http://www.php.net/array_merge($rf, $this->config['files']);
  49. $rf = http://www.php.net/array_merge(http://www.php.net/array_diff($rf, $this->config['disabled_files']));
  50. return $rf;
  51. }
  52.  
  53. private function processPlugins() {
  54. foreach($this->plugins as $k => $v) {
  55. $plugin = new $v;
  56. $this->fileContent = $plugin->process($this->fileContent);
  57. }
  58. }
  59.  
  60. private function loadFiles() {
  61. foreach($this->files as $k => $v) {
  62. $this->fileContent[$v] = http://www.php.net/file_get_contents($v);
  63. }
  64. }
  65.  
  66. private function getFileContent() {
  67. return $this->fileContent;
  68. }
  69.  
  70. public function setFileContent($content) {
  71. $this->fileContent = $content;
  72. }
  73.  
  74. public function save($dir = null) {
  75. foreach($this->fileContent as $k => $v) {
  76. file_put_contents($dir . $k, $v);
  77. }
  78. }
  79. }
  80.  
  81. class comments {
  82. function __construct() {
  83. }
  84.  
  85. function process($files) {
  86. foreach($files as $k => $v) {
  87. $files[$k] = php_strip_whitespace($k);
  88. }
  89. return $files;
  90. }
  91. }
  92.  
  93. function dump($dump) {
  94. http://www.php.net/print('<pre>');
  95. http://www.php.net/var_dump($dump);
  96. http://www.php.net/print('</pre>');
  97. }
  98.  
  99. $files = http://www.php.net/array(
  100.  'dirs' => http://www.php.net/array(''),
  101.  'disabled_dirs' => http://www.php.net/array(''),
  102.  'files' => http://www.php.net/array(''),
  103.  'disabled_files' => http://www.php.net/array(''),
  104. );
  105.  
  106. $pre = new PreProcessor();
  107. $pre->setConfig($files);
  108. $pre->setPlugins(http://www.php.net/array('comments'));
  109. $pre->start();
  110. $pre->save('new/');
  111. http://www.php.net/print 'Hehe, udalo sie preprocesorawac kod;)';
  112. ?>


Cytat
Albo inny pomysł - łańcuch przetwarzania powinien mieć postać: input -> processing -> output. Tzn. niech będzie interfejs odpowiedzialny za dostarczanie contentu - np. pobierając z pliku, pobierając z listy plików, itd. Drugi interfejs/klasa to główne przetwarzanie i obróbka zagregowanego contentu. A na koniec interfejs zapisujący wynik obróbki. Taki pipeline pozwala na elastyczne dopasowywanie do potrzeb i dopisywanie nowej funkcjonalności.

Najlepiej byłoby opracować coś takiego i wydać razem z autoloaderem...

edit: Coraz bardziej podoba mi się pipeline. Można nawet pójść trochę w stronę Cocoona: zrobić sobie drzewko przetwarzania, gdzie na wejściu (liść) jest input, na wyjściu (korzeń) output, a w środku cokolwiek - agregacja, filtrowanie, wycinanie komentarzy, itd.

Możesz bardziej łopatologicznie napisać ;]

Napisany przez: bela_666 10.04.2005, 09:35:42

Cytując manual

Cytat
file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance.

;]

Napisany przez: Nievinny 10.04.2005, 11:51:56

Ok, to jeszcze zakodować to przez Zend SafeGuard (chyba jakoś tak?) to zupełnie będzie nieczytelne..., nie ma jakiejś funkcji usuwającej tylko komentarze?

Napisany przez: bela_666 10.04.2005, 12:07:06

http://pl.php.net/php_strip_whitespace ?

[edit]
Co do requirów to jest to 'trochę' skomplikowane ;]

No bo tak możemy użyć 4 funkcji do załączenia pliku, ale to najmniejszy problem.
Większy problem jest z czymś takim

  1. <?php
  2. $abc = 'path/to/file.php';
  3. require_once($abc);
  4.  
  5. //albo 
  6. require_once(PATH . './../file.php'); //;]
  7. ?>


Macie jakieś sensowne pomysły jak to rozwiązać ?:]

Napisany przez: Nievinny 10.04.2005, 13:54:46

Bela -> tylko komentarze bez spacji, czyli wcięcia by pozostały...
I jeszcze mała wada, gdy podaję cały skrypt ze struktórą katalogową to jak wiadomo nie może zapisać plików w podkatalogach bo nie istnieją, a więc trzeba dorobić tworzenie katalogów odpowiednich (bo nie każy będzie kożystał ze zwalczania requirów) ;]

#---- EDIT ----#
Co do require to może http://pl.php.net/token_get_all() i T_REQUIRE, T_REQUIRE_ONCE i ewentualnie te z include?
Lum można szukać przeszukując ciąg za pomocą wyrażeń regularnych i pobierać to co pomiędzy require( 'czyli to' )?

Napisany przez: bela_666 10.04.2005, 21:40:20

Pocięcie do tokenów raczej nie załatwi sprawy, bo to analiza leksykalna a nie składniowa :] Byłoby trzeba napisać jakiś 'mini' analizator, który podmieniałby zmienne etc ;]

---
[edit]
nowa wersja ;]
http://openpb.net/work/dev/bela_666/phppl/preprocessor/

Napisany przez: hawk 11.04.2005, 08:45:30

@bela_666: łopatologicznie, hmmm... sam mam mgliste pojęcie. Wyobrażam sobie taki łańcuszek, gdzie można dowolnie przestawiać elementy. Na początku jest coś, co produkuje treść (np. czyta z pliku), na końcu coś, co konsumuje treść (np. zapisuje). Jakoś to skonfigurować, utworzyć łańcuch i niech pracuje.

Taki system może również np. czytać plik XML, robić na nim XSLT do kodu php i wiele innych rzeczy. Najważniejsze jest odseparowanie funkcjonalności związanej z czytaniem plików - dzięki temu można wziąć tą treść z innego miejsca.

Co do require, sprawa jest faktycznie bardzo skomplikowana. Zwłaszcza że niektóre require nie mają z góry określonej ścieżki. Jest ona ustalana w trakcie wykonania. Wg mnie, analiza tego jest z góry skazana na niepowodzenie i tak naprawdę niepotrzebna winksmiley.jpg. Przecież mamy wspaniały autoloader, który jest właśnie po to, aby nie trzeba było pisać ani jednego require. W wątku o autoloaderze pisałem, że jego główną zaletą jest wywalenie tych require, co pozwala dowolnie łączyć, dzielić i przesuwać pliki z kodem. Jedno idzie w parze z drugim.

Napisany przez: bela_666 11.04.2005, 19:02:57

Cytat(hawk @ 2005-04-11 08:45:30)
@bela_666: łopatologicznie, hmmm... sam mam mgliste pojęcie. Wyobrażam sobie taki łańcuszek, gdzie można dowolnie przestawiać elementy. Na początku jest coś, co produkuje treść (np. czyta z pliku), na końcu coś, co konsumuje treść (np. zapisuje). Jakoś to skonfigurować, utworzyć łańcuch i niech pracuje.

Taki system może również np. czytać plik XML, robić na nim XSLT do kodu php i wiele innych rzeczy. Najważniejsze jest odseparowanie funkcjonalności związanej z czytaniem plików - dzięki temu można wziąć tą treść z innego miejsca.

No to to rozumiem, i w ostatnim kodzie wzorowałem się na Cocoonie ( generatory, transformatory etc ;] ). Ale o co chodzi z tym drzewem i liscmi :]

Napisany przez: hawk 12.04.2005, 09:46:14

OK, przykład takiego drzewa:

Kod
a.xml -> a.php _
                 \_ ab.php
          b.php _/

Plik a.xml transformujemy (XSLT) do a.php, po czym sklejamy z b.php, wycinając np. whitespace, i zapisujemy ab.php.

Tego nie zrobisz twoim systemem, bo pluginy działają na wszystkich plikach i nie można wykonać transformacji XSLT tylko na jednej gałęzi.

Napisany przez: NuLL 12.04.2005, 10:47:55

Czy może mi się tylko wydaje czypoprsotu trzeba napisać podklasę liścia i nałożyć filtr czy jakieś transformatory na kazdy z osobna, lub ew. na wszystkie ?

Patrząc dalej - zmalować jakiś XML-owy konfig, że poinstruował PreProccesor co ma robić z danym liściem i jak zachoać się w danej sytuacji ? snitch.gif

Napisany przez: Vengeance 12.04.2005, 18:59:57

A czy mi się tylko wydaje, czy to wszystko jest poroniony pomysł snitch.gif

O ile samo "złączenie wszystko w jedno" to jeszcze zalicze do dobrych niekiedy spraw, to w takim "udziwnianiu" już nei widze sensu :]

ps. moje zdanie, nie krzyczcie ;P

Napisany przez: NuLL 12.04.2005, 19:38:06

Mimo iż dopisałem swoją wizję tego czegoś - to jest to dla mnie też zupełnie zbędne...

Vee - do własnego zdania ma prawo każdy smile.gif

Napisany przez: hawk 21.04.2005, 16:32:37

No dobra, jakiś bardziej praktyczny przykład takiego skomplikowanego preprocesora winksmiley.jpg.

Generowanie map dla autoloadera. Załóżmy, że chcemy wygenerować mapę, w skład której będą wchodzić pliki z kilku różnych katalogów. Nie chcemy mieć w niej niepotrzebnych plików. Oczywiście, można zrobić to na wiele różnych sposobów, ale jednym z nich jest właśnie system, który może pobierać dane (pliki) z różnych katalogów, zbierać razem i przesyłać dalej do przetwarzania.

Albo inaczej: chcę scalić 5 plików z kodem i 1 plik php z jakimiś danymi konfiguracyjnymi. Z całego kodu należy wyciąć komentarze i whitespace. Z danych konfiguracyjnych nie, i do tego mają znaleźć się na początku pliku, żeby po jego otworzeniu można było coś z tego wyczytać. Znowu, można zrobić to inaczej, można machnąć ręką, ale zastosowania są.

Gdyby tylko dało się to jakoś prosto składać w sensowny pipeline...

Napisany przez: Sedziwoj 9.04.2007, 18:12:33

Ktoś pisze interpreter PHP więc wiele można winksmiley.jpg

A co do samego pomysłu to mi też taki do głowy wpadł, tylko że czytając ten tekst doszedłem że to nie takie proste. A dokładnie to myślałem nad usuwaniem 'zbędnych' rzeczy, czyli odstępy, wcięcia, łamanie linii itp. oraz komentarzy. Co nie było by może zbyt trudne, jednak już przynosi pewne problemy.

Co do łączenia plików, to już jest problem, bo powstaje nam istny graf, w tym część gałęzi można poznać dopiero w czasie wykonywania... (mówię o ładowaniu w czasie wykonywania odpowiednich plików)

Ale skoro interpreter to zjada, to dlaczego my byśmy nie mogli tego zrobić biggrin.gif

Napisany przez: Zeman 9.04.2007, 23:04:46

Ja się dołączę do rozmowy.

Jak robiłem pluginy do mojego edytora mające za zadanie przerabianie plików PHP podczas kładzenia ich na serwer, nasunął się pewien "problem" o którym nie pomyślałem wcześniej, a mianowicie:

Plik php na serwerze ma inną postać niż edytowany w edytorze, a to powoduje błędne raportowanie o błędach, tzn standardowy komunikat "Parse error: syntax error, unexpected ',' in c:\usr\apache\httpd\html\zeman_serw\web2biz\index.php5 on line 3" nam może nic nie powiedzieć dgyż linia 3 na serwerze to już nie linia 3 w edytorze.

Oczywiście można z tym sobie poradzić, ale chciałem zwrócić uwagę, że takie coś będzie występować.

Napisany przez: Sedziwoj 9.04.2007, 23:38:13

Chyba raczej taki błąd się nie pojawi, ale na pewno będzie się rozchodziła numeracja.
To jest pewien problem, choć nie do końca, bo 'parse error' powinno być przed 'kompilacją' wyłapane, a późniejsze błędy, przy dobrej obsłudze będą niewiele gorzej lokalizowane (przy obiektowym programowaniu)

Napisany przez: cicik 12.04.2007, 21:16:36

Przyznam się, że mi taki pomysł też po głowie chodzi jednak w dużo bardziej rozbudowanej wersji.
Marzy mi się narzędzie, które po pierwsze zrobi to co proponujecie czyli poskleja odpowiednie pliki razem, wytnie białe znaki etc. ale również zrobi dokumentację kodu na podstawie komentarzy.
Coś jak PHPDocumentor tylko dużo szybsze i z kilkoma nowymi tagami - brakuje mi np. tagów do określania jakie wyjątki rzuca dana funkcja i kiedy. I generalnie chciałbym aby generowało to dokumentację na kształt MSDN w Visual Studio bo ona tam ejst naprawdę dobrze zrobiona.
Co więcej takie narzędzie musiałoby być napisane w jakimś C++ lub C# żeby działało szybciej.
Do tego można by jeszcze dorobić narzędzie do generacji klas do testów jednostkowych i narzędzie, które testuje pokrycie kodu testami (poprzez dołączenie do każdego ifa i pętli odpowiednich funkcji do sprawdzania czy coś się wywołało czy nie).

Generalnie potrzebne do tego wszystkiego byłoby napisanie jakiegoś porządnego parsera składni PHP aby można było plik z kodem zmienić na graf obiektów w danym języku. Ale o tym większego pojęcia jeszcze nie mam. Póki co napisałem tylko w C# profilera interpretującego plik wypluwany przez APD. Aczkolwiek marzy mi się właśnie napisanie całego takiego pakietu z narzędziami "około phpowymi".

Temat dość zaawansowany, pewnie na niejedną magisterkę ale gdyby to dobrze zrobić to nawet pewnie by się to sprzedać dało.

Pozdrawiam

Napisany przez: akubiczek 16.04.2007, 13:57:22

Skoro temat wyskoczył do góry, to dodam jeszcze odnośnie preprocesora, że przecież można wykorzystać nieśmiertelny cpp (c preprocesor) - który ma spore możliwości, a nie trzeba wynajdować koła od nowa smile.gif

Napisany przez: g00fy 21.07.2007, 23:51:55

widzialem i korzystalem z takiego programu , tylko ze on wszystko zamienial na EXE ;]

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