Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php Kanał ATOM (tag: php)

Autor wpisu: cojack, dodany: 26.03.2010 10:58, tagi: php

Dzisiaj w pracy kolega się mnie spytał czy jest taka możliwość by z klasy rodzica wywołać metodę w klasie dziecka, której nie ma w klasie rodzica. Urodził mi się uśmiech na twarzy i odparłem nie ma takiej możliwości, z logicznego pkt widzenia to jest awykonalne by w klasie bazowej móc wywołać metody z klasy, która dziedziczy nie definiując ich w tejże klasie bazowej. No ale spójrzmy co nam nasze php oferuje.

class A { 
  public function __construct(){ 
    $this->fuck(); 
  }  
}  
 
class B extends A { 
  public function __construct() { 
    parent::__construct(); 
  }  
 
  public function fuck() {
    echo "yo\n";
  } 
} 
 
$objB = new B();

A teraz zgadnijcie jaki będzie wynik, otóż zaskoczę Was, wynik to yo. A teraz wytłumaczenie dlaczego tak to działa:

“Obiekt jeszcze przed wywołaniem konstruktora klasy A już posiada wszystkie metody klasy B”

Innymi słowy metody są przypisane do obiektu a nie do klasy.

A żeby jeszcze było śmieszniej to kolejność wykonywania funkcji, popatrzcie sami:

class A { 
  public function __construct(){ 
    $this->fuck(); 
  }
 
  public function fuck() {
    echo "wow\n";
  }
}  
 
class B extends A { 
  public function __construct() { 
    parent::__construct(); 
  }  
 
  public function fuck() {
    echo "yo\n";
    parent::fuck();
  } 
} 
 
$objB = new B();

W kolejności wywoła się : yo a następnie wow. Dla mnie to powinna być pętla wow -> yo -> wow, a oczywiście jest inaczej.

Boże zlituj się nad developerami php i nie zważaj na grzechy ich.

Autor wpisu: Nikodem Ośmiałowski, dodany: 19.03.2010 00:11, tagi: php

W frameworku KohanaPHP w wersji 2.x były tzw. hooks czyli po naszemu miejsca w które można się wpiąć z własnym kodem. Przydawały się w różnych sytuacjach m.in do podpięcia niestandardowego routingu korzystającego z bazy danych. W najprostszym wydaniu mogło to wyglądać mniej więcej tak: function db_routing() { // routing po bazie danych } Event::add('system.routing', 'db_routing'); Taki rodem [...]

Autor wpisu: stormfly, dodany: 09.03.2010 14:48, tagi: php, sql

Mechanizm bardzo przydatny, umożliwiający przechodzenie do następnego lub poprzedniego rekordu z poziomu wybranego już rekordu. Dzięki temu użytkownik nie musi wracać do listy czy też z poziomu listy otwierać dziesiątek stron w osobnych zakładkach by je wszystkie...

Autor wpisu: Athlan, dodany: 07.03.2010 20:12, tagi: php, internet

Ostatnio byłem zobligowany napisać nową klasę tagów do mojego projektu Sypacz.pl, która de facto zachowała stare API, lecz rozszerzyła swoje funkcjonalności, więc w kodzie projektu nie było wielu zmian. Wena spowodowała to, że zacząłem pisać kod od zera.

Cały problem polega na tym, aby napisać na tyle elastyczną klasę tagów, która przyjmie nam zestaw danych, a następnie zaprezentować ją w formie chmury, czym zaopiekuje się arkusz stylów CSS:

Nazwa tagu => Ilość występowań

Parę osób mnie pytało, jak wyciągnąć takie informacje z bazy danych:

SELECT tag_name, COUNT(tag_name) AS tag_times FROM tags GROUP BY tag_name ORDER BY tag_times LIMIT 1, 50

Wykorzystałem obiekt Vframe_Attribute, aby ustandaryzować komponent względem pozostałych w moim frameworku. Jeżeli ktoś nie chce używać obiektu Attribute, może w prosty sposób przekształcić klasę tagów, otrzymując ten sam efekt, deklarując tylko atrybut chroniony protected $_aAttributes = array();. Temat chmury tagów wydaje mi się na tyle trywialny, że nie ma się co nad nim zbyt wiele rozwodzić, zamieszczę tylko klasę i opiszę krótko w przykładach jej możliwości.

  • Vframe_Tagcloud – klasa tagów,
  • Vframe_Attribute – pomocnicza klasa atrybutów dla stosu $_aAttributes, dziedziczenie można usunąć i zadeklarować atrybut samemu.

Aby stworzyć nowy obiekt tagów, po prostu wywołujemy konstruktor:

$oCloud = new Vframe_Tagcloud();

Konstruktor nie przyjmuje żadnych argumentów, wiec możemy od razu przejść do podawania obiektowi tagów. W tym miejscu warto nadmienić, że każdy znak jest rozróżniany (ze względów elastycznych), więc jeżeli chcesz, aby Nazwatagu oraz nazwatagu były rozpoznawane jako jeden klucz, wypadałoby użyć funkcji strtolower lub mb_strtolower (dla Multibyte Strings):

foreach($aDataTags as $iKey => $aRow)
  $oCloud->add(strtolower($aRow['tag_name']), $aRow['tag_times']);

Najistotniejszą częścią klasy jest sposób renderowania chmury, które może działać w dwóch trybach:

  • Tryb prosty zwraca nam nazwę tagu oraz jego wagę po przeliczeniu w formie liczby.
  • Tryb zaawansowany zwraca nam nazwę tagu oraz tablicę z danymi:
    • level – waga tagu po przeliczeniu,
    • count – ilość występowań, taka jaką podaliśmy,
    • count_percentage – informacja, w jakiej procentowej części ilości występowań znajduje się tag, przyjmując za 100% tag, który występuje najczęściej.

Aby w prosty sposób wyrenderować chmurę tagów, używamy poniższego przykładu:

$aDataTagsRender = $oCloud->render();

Najczęściej używa się trybu prostego. Oba tryby są dalej rozbudowane, bowiem mamy możliwość zdefiniowania zakresu i dokładności wag tagów. Domyślnie wagi tagów zawierają się pomiędzy 1, a 10. Możemy na przykład przyjąć, że najmniejszą wagą jest liczba 3, największą 5, a precyzja wag tagów to 2 miejsca po przecinku:

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

Autor wpisu: Zyx, dodany: 06.03.2010 10:57, tagi: php

Trac to jeden z najpopularniejszych otwartych systemów zarządzania projektem. Posiada wbudowany bugtracker, przeglądarkę repozytorium SVN oraz system wiki. W większości przypadków jest to zupełnie wystarczające, ale system ma też kilka wad. Inne systemy kontroli wersji obsługiwane są wyłącznie poprzez wtyczki, składnia wiki jest według wielu osób okropna, a ponadto może wystąpić problem z hostingiem, jako że całość napisana jest w Pythonie.

Autor wpisu: Vokiel, dodany: 24.02.2010 16:02, tagi: javascript, php, jquery, css

Na Grafish Design’s Blog natknąłem się na The Small Callendar. Czyli mały kalendarz, który umożliwia sprawdzenie wybranej daty pod kątem dnia tygodnia. Przedstawiony tam kalendarz jest wersją do druku (dostępny do pobrania w ponad 30 językach). Kalendarz ten różni się od standardowych tym, że ma tylko jeden blok z dniami miesiąca. Postanowiłem stworzyć taki kalendarzyk on-line przy wykorzystaniu PHP oraz odrobiny jQuery, plus oczywiście CSS.

ŹródłaDemo

Cel

Kalendarz w wersji oryginalnej wygląda następująco:

The Small Callendar

The Small Callendar - Grafish Design's Blog

źródło: Grafish Design’s Blog – The small calendar 2010 (en) .

Planowana przeze mnie wersja będzie miała:

  1. Wygląd przypominający oryginał
  2. Wybór roku innego niż aktualny
  3. Wielojęzyczność
  4. Możliwość podświetlania kolumny dat
  5. Możliwość podświetlania wierszy miesięcy
  6. Możliwość podświetlania dni tygodnia dla wybranych dat
  7. Możliwość przenoszenia bloku dat po kliknięciu na wiersz miesiąca

Generowanie kalendarza: PHP

Do wygenerowania kalendarza posłużymy się prostą klasą, która wygeneruje nam kilka rzeczy. Po pierwsze stworzymy listę miesięcy, dla każdego z nich sprawdzimy liczbę dni, sprawdzimy dzień tygodnia dla pierwszego dnia miesiąca. Następnie stworzymy na tej podstawie tablicę, która będzie zawierała skróty nazw miesięcy (w wybranym języku), dla wybranego roku, do każdego z miesięcy przypiszemy ilość dni oraz odpowiednio posortowane skróty nazw dni tygodnia.

Klasa ta jest bardzo prosta, zatem możemy ją nazwać imitacją klasy, zbiorem funkcji opakowanych w klasę. Lista metod:

  1. public __construct – 2 parametry opcjonalne: rok, tablica z danymi języka | konstruktor
  2. public setLanguage – 1 parametr: tablica z tłumaczeniami | ustawienie języka
  3. public getdatesTable – 0 parametrów | tworzy tablicę dni
  4. public getCalendar – 0 parametrów | pobiera tablicę z kalendarzem
  5. private generateMonths – 0 parametrów | generuje miesiące
  6. private generateDayNames – 0 parametrów | tworzy dni tygodnia w odpowiedniej kolejności

Kod klasy

Część po stronie serwera jest na tyle prosta, że nie wymaga większego opisu. Konstruktor może przyjmować 2 parametry: rok oraz tablicę z tłumaczeniem na inny język. Oba parametry są opcjonalne, domyślnym rokiem jest aktualny, język – polski.

Metoda setLanguage ustawia język. Kolejna, getDatesTable generuje tablicę z dniami miesięcy (1-31), oznaczając odpowiednio ilości dni wg miesięcy. getCalendar wywołuje dwie inne: generateMonths – generuję tablicę miesięcy, wraz z ważnymi danymi, oraz generateDayNames – generującą skrótowe nazwy dni tygodnia.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<?php
/**
 * VokielSmallCallendar class
 * @author Vokiel | http://blog.vokiel.com
 */
class VokielSmallCallendar {
	/**
	 * Selected year
	 * @var int	$year
	 */
	private $year;
	/**
	 * Shortcuts names for months
	 * @var	array $monthsShort
	 */
	private $monthsShort = array();
	/**
	 * Shortcuts names for week days
	 * @var	array	$daysShort 
	 */
	private $daysShort = array(); 
	/**
	 * Generated months table for the callendar
	 * @var array $months
	 */
	private $months = array();
 
	/**
	 * Construct, 
	 * @param	int	$year
	 * @param	array	$lang
	 */
	public function __construct($year=0,$lang=null){
		$this->year = ($year)? (int)$year : date('Y');
 
		if (!is_array($lang) || !is_array($lang['months']) || !is_array($lang['days'])){
			$lang = null;
		}
		$this->setLanguage($lang);
	}//end of __construct
 
	/**
	 * Setting the monts shortcuts names and days shorcuts names.
	 * Polish is default language.
	 * @param	array	$lang	Monts and days array starting from 1 = January and 1 = Monday
	 */
	public function setLanguage($lang=null){
		$this->monthsShort = (is_array($$lang['months']))? $$lang['months'] : array(1=>'Sty',2=>'Lut',3=>'Mar',4=>'Kwi',5=>'Maj',6=>'Cze',7=>'Lip',8=>'Sie',9=>'Wrz',10=>'Paź',11=>'Lis',12=>'Gru');	
		$this->daysShort = (is_array($$lang['days']))? $$lang['days'] : array(1=>'Pon',2=>'Wt',3=>'Śr',4=>'Czw',5=>'Pt',6=>'Sob',7=>'Nie');
	}//end of setLanguage method
 
	/**
	 * Generating the dates table (numbers from 1 to 31)
	 * @return	string	$datesTable	Generated HTML table
	 */
	public function getDatesTable(){
		$datesTable = '<table><tbody><tr>';
		for ($i=1;$i<32;$i++){
			$class = '';
			if ($i>=28){
				if ($i == $this->months[2]['daysCount'] || $i>29){
					$class = 'class="days_'.$i.'"';
				}
			}
			$datesTable .= '<td '.$class.'>'.$i.'</td>';
			if ($i%7==0){
				$datesTable .= '</tr><tr>';
			}
		}
		$datesTable .= '</tr></tbody></table>';
		return $datesTable;
	}//end of getdatesTable method
 
	/**
	 * Getting the calendar
	 * @return	array	$this->months Array with months shortcuts names and sorted week days shortcuts names	 
	 */
	public function getCalendar(){
		$this->generateMonths();
		$this->generateDayNames();
		return $this->months;
	}//end of getCalendar method
 
	/**
	 * Generating months table
	 */
	private function generateMonths(){
		for ($i=1;$i<13;$i++){
			$time = mktime(0,0,0,$i,1,$this->year);
			$this->months[$i]['weekDay'] = date('N',$time);
			$this->months[$i]['montShort'] = $this->monthsShort[$i];
			$this->months[$i]['daysCount'] = date('t',$time);
		}
	}//end of generateMonths method
 
	/**
	 * Generating week day names shortcuts
	 */
	private function generateDayNames(){
		foreach ($this->months as $month => $dayStart){
			$dayStart = $dayStart['weekDay'];
			for ($i=0;$i<7;$i++){
				$day = ($dayStart+$i>7)? (-(7-$dayStart-$i)) : ($dayStart+$i);
				$this->months[$month]['weekdays'][] = $this->daysShort[$day];
				unset($this->months[$month]['weekDay']);
			}
		}
	}//end of generateDayNames method
 
}// end of VokielSmallCallendar class

Obsługa kalendarza: JavaScript

W tej części zajmiemy się oskrytpowaniem kalendarza w JavaScript (korzystając z jQuery) w celu nadania mu funkcjonalności, dynamiki i użytecznosci. Z naszych założeń wynika, że musimy utworzyć kilka funkcji, które będą reagować na przesuwanie kursora myszki ponad polami kalendarza.

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

Autor wpisu: Michał Środek, dodany: 20.02.2010 17:53, tagi: php

Zająłem się ostatnio w analizą konfiguracji PHP oraz sprawdzaniem w jakich okolicznościach jest możliwe dołączenie lub podglądanie plików php znajdujących się na serwerze. W kilku artykułach postaram się wyjaścić większość znanych mi technik. Rozpocznę od dosyć prostych i oczywistych, a w kolejnych częściach będę podnosił poprzeczkę usprawniając konfigurację serwera. Dzisiaj zaprezentuję na czym polega atak LFI(Local File Inclusion) polegający na uruchamianiu pliku dostępnego na serwerze.

Na atak są podatne strony wykorzystujące takie funkcje jak np. file(), file_get_contents(), include(), include_once(), require() i inne czytające dane z jakiegoś pliku. Ważne aby w paramtr określający adres czytanych zasobów był zależny od jakiejść zmiennej przesłanej przez użytkownika. Przykładowy(bardzo popularny) kod:

include('strony/'.$_GET['page'].'.html');

Atak działa podobnie jak SQL Injection. Musimy tak spreparować adres aby odnosił się on do innego pliku. Spróbujmy wpisać:

example.com?page=../index

Skrypt powinien wczytać plik strony/../index.html czyli po prostu index.html. Problem stanowi rozszerzenie określone z góry przez programistę. Gdybyśmy się go pozbyli, możliwe byłoby dołączenie dowolnego pliku, do którego posiadamy uprawnienia. Zastanówmy się jednak w jaki sposób działają powyższe funkcje. Wiemy, że PHP jest pisany w C. Jako parametr podajemy ciąg znaków. Każdy programujący w C wie, że stringi w tym języku to po prostu tablice znaków wyglądające następująco:

Jakis ciag znakow\0

Znakiem który określa zakończenie napisu jest znak zero. Jest to spowodowane tym, że tablica może mieć większy rozmiar niż długość napisu. Jezyk C jest tak napisany, że sam nie zeruje wartośći w pamięci na które wskazujemy więc brak znaku zero powodowałoby wyświetlanie „śmieci“ z pamięci. Tak więc dobrym pomysłem byłoby wszczepienie znaku \0 do naszego zapytania. Spróbujmy wpisać w adresie strony coś takiego:

example.com?page=../index.php%00

Jak zinterpretuje to PHP? Do funkcji include() zostanie przekazany ciąg znaków strony/../index.php\0.html. Funkcja include otrzymując w parametrze tablicę znaków wybierze wszystkie aż do znaku \0. W ten sposób końcówka .html zostanie uznana za śmieci z pamięci. Jak się chronić przed tym atakiem? Wystarczy prosty test poprawności przesyłanych danych:

if( preg_match('/^[a-zA-Z0-9]*$/', $_GET['page']) )
  include('strony/'.$_GET['page'].'.html');

Ograniczenia? Niestety możemy uruchomić jedynie pliki znajdujące się na serwerze. Jest jednak kilka sposobów aby sobie z tym problemem poradzić. Następnym razem przedstawię jak uruchomić własny kod PHP w przypadku dziury przedstawionej w tym artykule oraz błędnej konfiguracji serwera.

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