post_ico4

PHP i C++ razem? A dlaczego nie?

PHP jest obecnie bezdyskusyjnie najpopularniejszym językiem programowania używanym w aplikacjach internetowych. Jego główną zaletą jest prostota i łatwość nauki (chociażby brak jawnych typów). Jednak, ma on także znaczne ograniczenia. PHP nie nadaje się do wykonywania bardziej zaawansowanych algorytmów – język nie posiada odpowiednich narzędzi do tworzenia abstrakcyjnych struktur danych. No to jak sam PHP nie ma takich możliwości, to połączmy go z C++…

Jak to zrobić?

Do uruchamiania programów napisanych w innych językach możemy użyć funkcji popen().


Za manualem:

resource popen ( string $command , string $mode )

Funkcja popen() wykonuje polecenie zawarte w $command – może to być np. program w C++ lub polecenie systemowe systemów operacyjnych UNIX. Parametr $mode określa zaś prawa dostępu do procesu. Funkcja zwraca (w przypadku sukcesu) uchwyt do uruchomionego procesu, w przeciwnym wypadku zwróci false.

Przykładowy program

Żeby zobaczyć jak to wygląda w praktyce stwórzmy prosty program do sortowania liczb. Wykorzystamy sortowanie bąbelkowe.

Najpierw stwórzmy kod w C++:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void boubleSort(int table[], int size) {
	int i, j, temp;
     for (i = 0; i<size; i++) {
		for (j=0; j<size-1; j++) {
			if (table[j] > table[j+1]) {
			 temp = table[j+1];
                table[j+1] = table[j];
                table[j] = temp;
            }
        }
	}
}

int main(int argc, char** argv) {
	int n=argc-1;
	int t[n+1];
	for(int i=0;i<n;i++) {
		stringstream konwersja(argv[i+1]);
		konwersja>>t[i];
	}
	boubleSort(t, n);
	for(int i=0;i<n;i++) {
		cout << t[i]<< " ";
	}
	return 0;
}

W liniach 5-16 zawarty jest algorytm sortujący. W wierszach 21-24 odbieramy i konwertujemy argumenty przekazywane przy uruchamianiu programu do typu int. Właśnie za pomocą tablicy argv będziemy przekazywać dane ze skryptu PHP. Linie 26-28 wyświetlają wynik na standardowym wyjściu (zostanie on przekazany do skryptu PHP).

Teraz stwórzmy skrypt PHP:

<?php
error_reporting(E_ALL);
$string='';
for($i=0;$i<400;$i++) {
	$x=rand();
	$string=$string." ".$x;
}

$handle = popen('./program '.$string, 'r');
$read = fread($handle, 1000000);
echo $read;
pclose($handle);

W liniach 4-7 generujemy liczby do posortowania za pomocą funkcji rand(), kolejno złączamy je w łańcuch znaków. W wierszu 9 uruchamiamy proces programu ./program z argumentami ze zmiennej $string, który zostaje przekazany do uchwytu $handle. W kolejnej linii sczytujemy zawartość standardowego wyjścia uchwytu $handle za pomocą funkcji fread(). Na koniec wyświetlamy już posortowane liczby ze standardowego wyjścia i zamykamy proces.

Po co to komu?

Tego typu połączenie może przydać się w specyficznych aplikacjach – gdy potrzebujemy dodatkowych narzędzi, nieposiadanych przez PHP. Najczęściej w celu optymalizacji i wykonania bardziej zaawansowanych algorytmów.

Ponadto, jako że kod C++ jest kompilowany, wykonuje się znacznie szybciej niż skrypt PHP. Zrobiłem testy dla powyższego programu i wyniki mówią same za siebie:

  • Dla powyższego programu posortowanie 400 liczb zajęło 0.00854 s.
  • Dla tego samego programu, ale napisanego tylko w PHP, sortowanie zajmuje 0.02844 s.

Wyniki mówią same za siebie.

W niedalekiej przyszłości postaram się pokazać bardziej praktyczny przykład takiego połączenia. W końcu język to tylko narzędzie programisty …

Co sądzisz o wpisie?
BeżnadziejnySłabyŚredniDobryBardzo dobry (Brak ocen, bądź pierwszy!)
Loading...
  • Nie powalił mnie ten wpis. A samo popen() jest raczej wprowadzone po to by otworzyć potok z/do istniejącego już unixowego programu. No i generalnie w dużej mierze zależy od konfiguracji danego środowiska.

    Polecam poczytać o pisaniu rozszerzeń C++ do PHP, poprawnie napisane zadziałają i na Unixach i na Windowsach, nie ma problemu z zależnościami i ścieżkami, generalnie bardziej pragmatyczne i eleganckie podejście.

    Oczywiście do prostych rzeczy można Twojego rozwiązania użyć, kwestia potrzeb oczywiście ;)

    http://devzone.zend.com/article/4486

  • Ano wiadomo, jak to w programowaniu bywa, jest wiele sposobów na rozwiązanie danego problemu :)

    Wgryzę się w ten temat i zaprezentuję jeszcze inne sposoby połączanie PHP z programami pisanymi w innych językach ;)

  • Marek

    Czekamy niecierpliwie na cz.2 moim zdaniem temat jest bardzo interesujący i różne sposoby łączenia PHP ze „światem” dają wiele możliwości.

    Kilka lat temu pisałem serwer www, w C++ umożliwiający sterowanie portem LPT przy pomocy zmiennych POST wysyłanych do serwera, przy czym analiza danych odbywała się w samym serwerze, PHP mogło natomiast pobrać stan portu LPT.
    Całość służyła do sterowania dowolnymi urządzeniami przy pomocy prymitywnej strony :)

  • mmtt

    Rzucił mi się od razu błąd w kodzie c++, definiujesz sobie tablicę int w taki sposób: „int t[n+1];”, przy czym n jest zmienną. Jest to zabieg niepoprawny, ponieważ liczba pomiędzy nawiasami kwadratowymi w deklaracji tablicy musi być stałą (chociażby const int). Jeżeli koniecznie potrzebujesz tablicy, której rozmiaru nie znasz w czasie pisania programu, należy użyć funkcji new.

  • Internauta

    „Może zainteresują ciebie także te wpisy:” – cóż za dziwaczna prezentacja listy. Nie znasz się na web usability.

    • Blog stoi na gotowym szablonie. Po prostu nie mam w tym momencie tyle czasu, by każdy element dopracowywać.