Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Zyx, dodany: 28.02.2009 15:41, tagi: php

Czy zastanawialiście się, dlaczego oskryptowanie stron WWW tworzy się w językach takich, jak PHP, a nie C czy C++? Albo dlaczego nie używa się w miejsce C Pascala? Popularność zdobyta przez te języki wynikała z faktu innowacyjności oraz trafienia w potrzeby ludzi, pozwalając szybciej i łatwiej tworzyć aplikacje. Jednak w tym wpisie pragnę skupić się na systemach szablonów, właśnie w kontekście tych bagatelizowanych przez wielu spostrzeżeń.

Autor wpisu: normanos, dodany: 20.02.2009 15:47, tagi: php, framework, php5

Dzisiaj będzie szybko, krótko, treściwie, niczym po żołniersku Jestem zakręcony z powodu kończenia kolejnego projektu dla klienta oraz poniedziałkowego wylotu do ciepłych krajów; szok, że udało mi się coś nowego napisać (ale o prokrastynacji i GTD będzie innym razem, obiecuję). Kohana Projects to długo oczekiwany serwis (oparty na popularnym ostatnio (tfu) Railsowym Redmine) mający [...]

Autor wpisu: Athlan, dodany: 19.02.2009 14:19, tagi: apache

Wiele razy zdarzało mi się, że mój serwer padł całkowicie lub przerywał żądania. Wówczas był niedostępny, a zarobki generowane z serwisów diametralnie spadały. Co więcej… użytkownicy poczuli niestabilność maszyny. Dziś po odpowiedniej optymalizacji kodów aplikacji pady są rzadkością, ale wolę się ubezpieczyć przed niespodziewanym downem serwera.

Problem można rozwiązać w prosty sposób: cyklicznie uruchamiany program bash‘a przez crona będzie odpowiadał za poprawne działanie usługi apache. Listing, który zaprezentuję łączy się z adresem url odwołującym się do naszego serwera za pomocą wget, a następnie wynik działania (response body) zapisze do pliku tymczasowego. Jeżeli plik istnieje oraz ma rozmiar niezerowy, oznacza to, że serwer działa poprawnie. Jeżeli plik nie istnieje, bądź jego wielkość jest równa zero z, oznacza to, że trzeba zrestartować usługę apache, bo nie odpowiada. Zaraz przed zakończeniem programu, plik tymczasowy powinien zostać usunięty. Pozwoliłem sobie opublikować mały program służący do automatycznego restartu usługi apache.

Aby nasz program poprawnie działał, trzeba zastanowić się nad trzema istotnymi rzeczami:

  1. Ile prób połączenia ma wykonać wget oraz jakie mogę być timeouty.
  2. Czy adres url, do którego się odwołujemy będzie zawsze dostępny w przypadku poprawnego działania usługi apache.
  3. Jaki powinien być interwał uruchamiania napisanego programu.

Na moim serwerze program uruchamia się co minutę, próbuje połączyć się ze stroną dwa razy, a maksymalny czas oczekiwania na odpowiedź przy każdej z prób wynosi 10 sekund.

Program zapisany jest pod /root/check_apache.sh, a regułka uruchamiania w cronie wygląda następująco:

* * * * *       bash /root/check_apache.sh

Przedstawiony problem można rozwiązać na wiele sposobów, przedstawiłem ten najbardziej oczywisty.

Autor wpisu: Tomasz Sh4dow Budzyński, dodany: 15.02.2009 23:01, tagi: php

Autoload w PHP istnieje od wersji 5.0. Bardzo przydatna „magiczna” funkcja, która potrafi zaoszczędzić trochę zasobów serwera. Ładuje pliki z klasą jedynie w czasie gdy jest ona potrzebna. Rozwiązań jest za pewne wiele, niektórzy przeszukują za każdym razem system plików za nazwą klasy, a niektórzy tworzą specjalne konstrukcje katalogów. Są też rozwiązania ze stworzeniem tablicy z nazwami klas i ścieżką do plików.
I to rozwiązanie jest moim zdaniem najbardziej efektywne. Jedynym problemem jest tworzenie takiego pliku z tablicami. Oczywiście możemy ręcznie tworzyć tablice, to jest wersja dla najtwardszych. Innym sposobem jest oczywiście stworzenie prostego narzędzie do tworzenia takiej tablicy.

Pierwsza rzecz to musimy wyszukać wszystkie pliki jakie chcemy przeszukać.

<?php
$path = './';
$dir = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST
);
 
foreach($dir as $file) {
    //przetwarzanie plików
}
?>

To nam pomoże przeszukać wszystkie pliki php w danym katalogu oraz jego podkatalogach. Jeśli ktoś używa na przykład skryptu Smarty, to pojawia się dużo plików php które napewno nie posiadają żadnej klasy lub też katalogi .svn posiadające dużo plików, gdzie nie znajdziemy niczego nam potrzebnego. Przydało by się to odfiltrować. Np przykład tak:

<?php
if( $file->isFile() 
    and end( explode( '.', $file->getFilename() ) ) == 'php' 
    and strpos($file->getFilename(), '%') === false 
    and strpos( $file->getPath().'/'.$file->getFilename(), '.svn') === false ) {
    //dalsze przetwarzanie plików
}
?>

Pre-kompilowane szablony smarty posiadają znaki ‘%’ więc takie pliki możemy odrzucić. Możemy się pokusić o odrzucenie plików z katalogu gdzie zapisywane są pliki smarty, ale w przypadku zmiany nazwy katalogu, trzeba by było modyfikować skrypt. Wszystkie pliki które posiadają w ścieżce fragment ‘.svn’ także będziemy odrzucać, ponieważ na pewno tam nic nie znajdziemy.

Teraz przystąpimy do samego wyszukiwania klas w plikach. Skorzystamy  z wbudowanej funkcji w token_get_all, która częściowo przetworzy nam kod PHP na poziom leksykalny, co znacząco ułatwi nam wyszukiwanie potrzebnych nam rzeczy. Zasadę może pokaże na przykładzie:

<?php
 
# przykładowa klasa
# <?php
# class NazwaKlasy {
#     //tresc klasy
# }

var_dump( token_get_all( "<?php\n class NazwaKlasy {\n //treść klasy\n }") );
?>

Wynikiem będzie wyświetlenie tablicy 2 wymiarowej. W tym konkretnym przykładzie będzie posiadała ona 11 elementów na pierwszym poziomie. Każdy taki element opisuje pojedynczą jednostkę leksykalną. Listę takich jednostek znajdziecie w dokumentacji PHP. Jak znaleźć nazwę klasy. Każdy znaleziony element jest albo string’iem dla znaków takich jak ( ‘{‘, ‘}’, ‘;’, ‘.’, ‘>’, itp.) lub tablicą 3 elementów. Pojedyncze znaki nas nie interesują, więc szukamy tablic. A dokładniej ułożenia kolejnych 3 elementów. Pierwsze to słowo kluczowe ‘class’ (token T_CLASS), następnie odstęp (white space, token T_WHITESPACE) a na końcu ciąg znaków ( token T_STRING ). I właśnie ten ostatni element w połączeniu z nazwą i ścieżką pliku potrzebny. Więc przetworzenie pliku będzie wyglądać mniej więcej tak:

$tokens = token_get_all( file_get_contents( $file->getPath().'/'.$file->getFilename() ) ); //odczytujemy plik i przetwarzamy
$count = count($tokens); //zliczamy ilość elementów, poprostu optymalizacja dla pętli
for($a=0; $a<$count;$a++ ) {
    if( is_numeric( $tokens[$a][0] ) ) { //sprawdzamy czy element jest opisany tablicą
        if( $tokens[$a][0] == T_CLASS and $tokens[$a+1][0] == T_WHITESPACE and $tokens[$a+2][0] == T_STRING ) { //spełnienie warunku dla kolejnych trzech elementów
            if( isset( $klasy[ trim( $tokens[$a+2][1] ) ] ) ) { //sprawdzenie czy nie istnieją duplikaty klas.
                $double[] = array( trim( $tokens[$a+2][1] ), $file->getPath().'/'.$file->getFilename() );
            } else {
                $klasy[ trim( $tokens[$a+2][1] ) ] = $file; //tworzenie tablicy ze ścieżkami do plików oraz nazwami klas
            }
        }
    }
}

Teraz pozostaje nam tylko otrzymaną tablice zapisać do pliku php. Co chyba nikomu nie sprawi problemu:

<?php
file_put_contents('autoload.array.php', "<?php\n");
foreach( $klasy as $class => $file ) {
	//zapisujemy skrócone ścieżki od aktualnego katalogu w górę
	file_put_contents('autoload.array.php', '$autoload[\''.$class.'\'] = \''.str_replace( getcwd(), '.', realpath($file) ).'\';'."\n", FILE_APPEND);
}
?>

W całości będzie to wyglądać mniej więcej tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
set_time_limit(0);
$klasa = array();
$path = './';
$dir = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST
);
 
//przetwarzanie plików
foreach($dir as $file) {
	if( $file->isFile() and end( explode( '.', $file->getFilename() ) ) == 'php' and strpos($file->getFilename(), '%') === false and strpos( $file->getPath().'/'.$file->getFilename(), '.svn') === false) {
        $tokens = token_get_all( file_get_contents( $file->getPath().'/'.$file->getFilename() ) );
        $count = count($tokens);
        for($a=0; $a<$count;$a++ ) {
            if( is_numeric( $tokens[$a][0] ) ) {
                if( $tokens[$a][0] == T_CLASS and $tokens[$a+1][0] == T_WHITESPACE and $tokens[$a+2][0] == T_STRING ) {
                    if( isset( $klasy[ trim( $tokens[$a+2][1] ) ] ) ) {
                        $double[] = array( trim( $tokens[$a+2][1] ), $file->getPath().'/'.$file->getFilename() );
                    } else {
                        $klasy[ trim( $tokens[$a+2][1] ) ] = $file;
                    }
                }
            }
        }
	}
}
 
//budowanie pliku z tablicą
file_put_contents('autoload.array.php', "<?php\n");
foreach( $klasy as $class => $file ) {
	file_put_contents('autoload.array.php', '$autoload[\''.$class.'\'] = \''.str_replace( getcwd(), '.', realpath($file)).'\';'."\n", FILE_APPEND);
}
?>

Na początku przydaje się dodać set_time_limit() na zero ponieważ przy dużych plikach oraz przy dużej ich ilości cała operacja może chwilkę potrwać. Należy pamiętać, że po dodaniu nowej klasy, przydałoby się uruchomić skrypt ponownie, aby dodał nową klase do tablicy.
Teraz pozostaje nam stworzyć jedynie funkcje __autoload, która będzie korzystać z naszej tablicy.

1
2
3
4
5
6
7
8
9
10
11
$autoload = array();
function __autoload($class_name) {
	static $autoload;
	include_once( './autoload.array.php' );
 
	if( isset( $autoload[ $class_name ] ) ) {
		include_once($autoload[ $class_name ]);
		return true;
	}
	return false;
}

I mamy gotową całą funkcjonalność autoload. Możemy ją poszerzyć o zliczanie ilości plików lub klas, czas wykonywania lub inne mniej lub bardziej przydatne informacje. Wszystko zależy od waszych potrzeb.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: m1chu, dodany: 15.02.2009 13:55, tagi: php

Pobieramy liczbę subskrybentów RSS poprzez FeedBurner

W niezbędniku prawie każdego blogera leży możliwość menadżerowania swoimi kanałami RSS, bądź Atom. Któż z nas nie zna FeedBurner'a?. Zestawu narzędzi ułatwiających nam, czy to udostępnianie użytkownikom możliwości subskrypcji treści naszej strony, czy po prostu możliwość przejrzenia lub zamieszczenia statystyk w naszym serwisie. Pomimo dostarczonego API nie znajdziemy jednak bezpośrednio w panelu FeedBurner'a kodu pozwalającego na umieszczenie samej liczby subskrybentów bloga. I rozwiązanie tego, pozornie błahego problemu postaram się Wam dziś przedstawić...

Stary, dobry FeedBurner.com...

Niespełna dwa lata temu słynny serwis zajmujący się obsługą kanałów RSS został przejęty za sto milionów dolarów przez Google. Pomimo tego, że minęło aż tyle czasu wielu blogerów nadal korzysta z zasobów starego, wysłużonego, pierwotnego FeedBurner'a. I co może wydawać się dziwne, to właśnie oni mają najbardziej ułatwioną sytuację.

Zarówno stara, jak i nowa odsłona serwisu oferują usługę FeedCount dostępną z poziomu menu Publicize. Pozwala ona na dobranie typu wbudowanego tła wyświetlającego ilość subskrybentów (statyczne, bądź animowane) oraz na dobranie jego barwy i koloru tekstu. Wraz z ustawieniem tych parametrów otrzymujemy kod HTML do wstawienia na naszą stronę. I tu rodzi się problem. Prócz kilku stylistycznych zmian wygląd tychże "chickletów" jest zawsze taki sam i najczęściej nijak pasuje do designu naszego bloga. Co zrobić jeżeli np. chcemy wraz z tekstem przycisku odnoszącego użytkowników do wygenerowanego kanału wstawić także ilość osób śledzących naszą stronę?

Rozwiązanie zaprezentuje na podstawie użytkowania platformy Wordpress (oczywiście ilość subskrybentów - opierając się na dalszym tekście - można zamieścić w każdym innym systemie zarządzania treścią, bądź nawet na własnej, prywatnej stronie). W takim wypadku wystarczy zainteresować się wtyczkami FeedSmith 2.3 (polska wersja) (wg. developerów Wordpress'a kompatybilną ze wszystkimi wersjami 2.x) i Feed Count 1.2 (polska wersja). Pierwsza z nich niezbędna jest do obsługi kanału RSS przez serwis FeedBurner.

Jej instalacja oraz rejestracja w serwisie jest niezbędna do działania drugiej z nich. Jak wykonuje się instalacje wtyczek? Wystarczy wyodrębnić z archiwum odpowiednie pliki (w naszym pierwszym przypadku będzie to FeedBurner_FeedSmith_Plugin.php, w drugim feedcount.php) i umieścić je w katalogu wp-content/plugins/ systemu Wordpress. Następnie wtyczki należy zaktywować w panelu administratora (Wtyczki / Nazwa wtyczki / Włącz).

Obydwa pluginy należy dodatkowo skonfigurować w zakładce Ustawienia. Pierwszy z nich swoje opcje ukrywa w podmenu FeedBurner. Zobaczycie tam dwa pola do uzupełnienia, jedno wymagane, drugie opcjonalne. Pierwsze z nich to pełny odnośnik do feedu strony w serwisie FeedBurner (i dla starej odsłony, i dla nowej na serwerach Google), a drugi to link do kanału RSS komentarzy.

Konfiguracja wtyczki FeedSmith w panelu
Konfiguracja wtyczki FeedSmith w panelu.

Co do drugiego rozszerzenia to działa ono dla wersji 2.x Wordpress'a, z tymże przy najnowszej 2.7x może sprawiać problemy natury zwracania wyniku w postaci N/A zamiast poprawnej wartości.

Konfiguracja wtyczki Feed Count w panelu
Konfiguracja wtyczki Feed Count w panelu.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: Kamil Adryjanek, dodany: 13.02.2009 22:26, tagi: php, symfony

I was wondering if there is any simple way in Symfony for calling cron job. I found in the documentation that we can use Batch files - it is kind of PHP script that looks similar to symfony front controller, all we need to do is to initalize symfony, parse project and application Configuration. Quite cool but there is better way (just in my opinion) to access all symfony features from the command line: tasks.
Every time we are creating project, generating modules, building models/forms we use standard symfony tasks. Task are grouped by namespace and name - this allows us to build intuitive script names. For example namespace: propel or doctrine, and the task name: build-model, build-sql. Why we should use tasks instead of batch files? Tasks are really simple, powerful and they take care of parsing command line arguments and options, initalizing needed configuration and classes. To create a simple task we have to create a class that exetend sfBaseTask and put it into lib/task/ directory. File name must ends with “Task.class.php” to be properly loaded.
Another great thing about tasks is that Symfony also provide task for generating new, custom tasks :)

symfony generate:task namespace:task

Using symfony generate:task task we can also use some options:
–brief-description - w can put some description for our task that we will after calling help
–use-database - allow us to use our database classes in task. By default set to propel
–dir - task directory, default lib/task/

For more information call:

symfony help generate:task

After generating we need to custimize our task. We can use our standard Propel/Dcotrine class to get/update data from the database. Simple example:


<?php

class updateUsersTask extends sfBaseTask
{
  protected function configure()
  {
    $this->namespace = 'user';
    $this->name = 'update-statuses';

     $this->briefDescription = 'Updates users status';
     $this->detailDescription = 'Updates users status';
  }

  protected function execute($arguments = array(), $options = array())
  {
    $databaseManager = new sfDatabaseManager($this->configuration);

	$this->log('Updating users statuses...');

	$this->log( sprintf('%d users were successfully updated', UserPeer::updateUsersStatuses( ) ));
  }
}

?>

Body of the function updateUsersStatuses is not important now.
Now we can simple call in commad line prompt:

symfony user:update-statuses

We should get nice message about how many users were updated.
As we have access to the script from the command line we should not have any problems with putting it into crontable to update users statuses (in this case) periodically. For example

* * * * * php /path/to/project/symfony user:update-statuses

where:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: m1chu, dodany: 09.02.2009 13:45, tagi: css

Efekt podświetlania w jQuery i Prototype

Jedni nie korzystają z nich wcale, niektórzy tylko po to aby zwiększyć funkcjonalność tworzonych przez siebie stron, a u jeszcze innych zauważalny jest przepych tego typu rozwiązań. Biblioteki programistyczne języka JavaScript, bo o ich wykorzystaniu tu mowa to źródło bardzo różnorodnych, nie tylko funkcjonalnych, ale także estetycznych efektów. Sieć aż kipi od dobrych i słabych, lepiej oraz słabiej wytłumaczonych przykładów użycia możliwości MooTools, jQuery, Prototype z Scriptaculous, czy innych mniej powszechnych frameworków.

Jednym z takich efektów jest możliwość stworzenia animowanego, graficznego podświetlenia pojawiającego się np. nad grafiką wywołującą animację. Interaktywność taka została opisana na NetTuts z wykorzystaniem MooTools. My osiągniemy taki wynik dzięki zastosowaniu jQuery (w jednym przykładzie) oraz dodatkowo także za pomocą Prototype wraz z Scriptaculous (w drugim przykładzie).

Oczekiwany efekt
Oczekiwany efekt.

Krok 1: Za co się chwycić na początku...

Na początek musisz wiedzieć w jakim celu potrzebny jest Ci prezentowany w tym artykule efekt. Menu? Wyświetlanie dodatkowych informacji w graficznej liście produktów? Czy może szybki, animowany splash? Wybór jest Twój i podług niego będziesz musiał zaopatrzyć się w dodatkowe, niezbędne elementy do wykonania podświetlenia.

Chodzi tu mianowicie o grafiki, których musi być dwa razy więcej niż elementów podatnych na działanie mechanizmu. Powiedzmy, jeżeli chcemy w pięcioelementowym menu zastosować w każdym zdarzenie po najechaniu myszką zgodne z przesłaniem tego artykułu to potrzebujemy dziesięciu grafik. Pięć opisujących przyciski menu i drugie tyle będące "treścią" pojawiającą się po podświetleniu.

Po uporaniu się z wizualną częścią problemu oraz strony internetowej możemy ruszyć krok dalej.

Krok 2: Zaopatrujemy się w jQuery i/lub Prototype i Scriptaculous!

jQuery to aktualnie najpopularniejsza biblioteka. I najłatwiej ją skatalogować w czeluścia własnego projektu. Wystarczy ze strony głównej pobrać wersję 1.3.1 production/Minified i umieścić ją w obrębie plików tworzonego przez nas przykładu (niezbędny będzie tylko plik jquery-1.3.1.min.js).

Z Prototype sprawa jest ciut bardziej skomplikowana, bo prócz standardowego frameworka musimy pobrać także dodatkowy interfejs w postaci Scriptaculous, dzięki któremu uzyskamy dostęp do efektu pozwalającego na dynamiczne zmienianie właściwości CSS elementów strony. Ściągamy więc wersję 1.6.0.3 pierwszej biblioteki, oraz paczkę z wersją 1.8.2 drugiej. Z obydwu wyodrębniamy pliki i w ramach folderu tworzonego przez nas projektu umieszczamy tylko prototype.js oraz effects.js (z drugiego archiwum).

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.