Notatnik Webmastera : PHP ...



Obserwuj zmiany wprowadzane na tej stronie | Wersja do druku | Zaloguj się:   Hasło:  

Wchodzicie tu często. Popatrzcie też na inne zapiski. Współtwórzcie tą wiki.



Linki


Frameworki

Dodatki

Skrypty

Skrypt pozwalający na ładowanie plików na serwer, z paskiem postępu. http://www.webdice.org/uber_uploader/

Debugowanie

Ogromne usługi podczas debugowania oddaje funkcja debug_backtrace()

Ciekawostki

Inkrementacja stringów

<?php

    $i 
"abcdz";
    echo ++
$i;

?>

daje w efekcie napis abcea

Cyfry i litery w inkrementowanym napisie traktowane są tak jakby cały napis był liczbą. Skrajnie prawy znak jest zwiększany o 1 (przy czym jeżeli jest to Z, z, 9 to zostanie zamieniony odpowiednio na a, A, 0 i w identyczny sposób zostanie zinkrementowany znak na lewo od niego).

Bitowe operacje logiczne na stringach

Operacje &, |, ^, ~ można stosować nie tylko do integerów ale także do stringów. Wtedy stringi biorące udział w operacji są traktowane jak ciągi bajtów. Każda para bajtów poddawana jest operacji logicznej, a bajty wynikowe są zwracane również jako string.

Wychodzenie z pętli

Instrukcje break i continue pozwalają na podanie numeru oznaczającego z której z zagnieżdżonych pętli wyjść.

Np. jak poniżej:
<?php

for($i=1;$i<10;$i++) {
    for(
$j=1;$j<10;$j++) {
        echo 
"$i*$j=".($i*$j)."<br>";
        if(
$i==&& $j==3) break 2;
    }
}

?>

Różnica między include a require

Jeżeli include nie jest w stanie dołączyć pliku to generuje warrning i idzie dalej a jeżeli require nie jest w stanie dołączyć pliku to generuje error i zatrzymuje się. Innych różnic nie ma.

wykonanie unset na zmiennej będącej referencją kasuje tylko tą zmienną a nie zmienną, do której jest referencja

<?php
$a 
5;
$b =& $a;
unset(
$b);
echo 
$a;  // wypisze 5
?>

wywołanie wewnątrz __call() niestniejącej metody tego samego obiektu

<?php
class Test {
  function 
__call($method,$args) {
    
$this->nieistniejacaMetoda();
  }
}
$t = new Test();
$t->jakakolwiekMetoda();  // spowoduje wywalenie się php na twardo na skutek nieskończonej rekurencji
?>

Wywałka następuje niezależnie od tego czy wyołujemy metodę przy pomocy $this-> czy przy pomocy call_user_func...
Wolno natomiast wywołwywać istniejące metody, albo metody, które nasza __call() potrafi obsłużyć bez wywoływania nieistniejących metod tego obiektu (czyli jeżeli rekurencja nie nastąpi albo zostanie przerwana w porę).

Nowości w PHP5

Funkcja __autoload()


Jeżeli odowłujemy się do niezdefiniowanej klasy i zadeklarowaliśmy wcześniej funkcję __autoload($className) to zostanie ona wywołana a jako parametr zostanie przekazana nazwa niezdefiniowanej klasy.
Jeżeli w ciele tej funkcj zadeklarujemy brakującą klasę (np. includując plik zawierający jej definicję) to wszystko będzie ok. Przy pomocy tej funkcji można sobie zapewnić ładowanie klas dopiero wtedy gdy są potrzebne zamiast includować je wszystkie zawsze.

Przykładowa funkcja __autoload()
<?php

function __autoload($className) {
    require_once(
dirname(__FILE__)."/inc/classes/$className.php");    
}

?>

Metody __get() __set() __unset() __isset() i __call()


Jeżeli zdefiniujemy w klasie metodę __get($propertyName) to jeżeli potem spróbujemy odczytać jakieś pole obiektu tej klasy np. tak $obj->pole2 to zamiast zwykłego odczytania zostanie wywołana metoda __get() z wartością “pole2” przekazaną w parametrze.
Analogicznie metoda __set($propertyName,$value) jest wywoływana zamiast zapisu do właściwości obiektu, a metoda __call($methodName,$args) zamiast wywołania każdej metody obiektu.
Pozwala to kontrolować dostęp do pól i metod danej klasy.

Poniższy przykład pokazuje jak przez zdefiniowanie funkcji __call() można osiągnąć sytuację, w której wszelkie wywołania metod danej klasy obsługuje zupełnie inna klasa.
<?php
class HelloWorld {
  function 
display($count)
  {
    for (
$i 0$i $count$i++) {
      print 
"Hello, World\n";
    }
    return 
$count;
  }
}
class 
HelloWorldDelegator {
  function 
__construct()
  {
    
$this->obj = new HelloWorld();
  }
  function 
__call($method$args)
  {
    return 
call_user_func_array(array($this->obj $method),$args);
  }
  private 
$obj;
}

$obj = new HelloWorldDelegator();
print 
$obj->display(3);
?>

Używanie nawiasów kwadratowych dla obiektu


Czasem wygodnie jest używać zwykłych nawiasów kwadratowych po to żeby zrelizować operację podobną do odczytu z tablicy (czy zapisu do niej) ale nieco bardziej skomplikowaną (np. zaglądającą do pliku czy bazy danych).
Można to zrobić implementując interfejs ArrayAccess tak jak w poniższym przykładzie.

<?php

class UserToSocialSecurity implements ArrayAccess {
  private 
$db// An object which includes database access methods
  
function offsetExists($name) {
    return 
$this->db->userExists($name);
  }
  function 
offsetGet($name) {
    return 
$this->db->getUserId($name);
  }
  function 
offsetSet($name$id) {
    
$this->db->setUserId($name$id);
  }
  function 
offsetUnset($name) {
    
$this->db->removeUser($name);
  }
}
$userMap = new UserToSocialSecurity();
print 
"John's ID number is " $userMap["John"];

?>

Niestety to jest bardzo niedoskonała funkcja ... np. nie da się zrobić $userMap["John"] = array(); $userMap["John"][] = “test”; bo dostaje się błąd «Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference”, którego nie da się w żaden sposób naprawić (http://bugs.php.net/bug.php?id=34783).
Zamiast notacji z nawiasami kwadratowymi lepiej używac notacji obiektowej -> dzięki funkcjom __get() __set() itd. jest o wiele bardziej elastyczna.

foreach przechodzący po polach obiektu

Konstrukcji foreach można używać nie tylko do przebiegania po tablicy ale także do przebiegania po polach obiektu tak jak poniżej:
<?php
class MyClass {
  public 
$name "John";
  public 
$sex "male";
}
$obj = new MyClass();
foreach (
$obj as $key => $value) {
  print 
"obj[$key] = $value\n";
}
?>

Standardowy sposób przechodzenia po obiekcie można zmienić implementując w tym obiekcie inrefejs Iterator jak w poniższym przykładzie:
<?php
class NumberSquared implements Iterator {
  public function 
__construct($start$end)
  {
    
$this->start $start;
    
$this->end $end;
  }
  public function 
rewind()
  {
    
$this->cur $this->start;
  }
  public function 
key()
  {
    return 
$this->cur;
  }
  public function 
current()
  {
    return 
pow($this->cur2);
  }
  public function 
next()
  {
    
$this->cur++;
  }
  public function 
valid()
  {
    return 
$this->cur <= $this->end;
  }
  private 
$start$end;
  private 
$cur;
}
$obj = new NumberSquared(37);
foreach (
$obj as $key => $value) {
  print 
"The square of $key is $value\n";
}
?>

Jeżeli chcemy wywalić rzeczy związane z iteratorem do osobnego obiektu po to żeby nie mieszały nam się z danymi obiektu po którym chcemy spacerować to możemy to zrobić implementując w naszej klasie interfejs Iterator Agregate? i tworząc dodatkową klasę implementującą interfejs Iterator tak jak w poniższym przykładzie:

<?php

class NumberSquared implements IteratorAggregate {
  public function 
__construct($start$end)
  {
    
$this->start $start;
    
$this->end $end;
  }
  public function 
getIterator()
  {
    return new 
NumberSquaredIterator($this);
  }
  public function 
getStart()
  {
    return 
$this->start;
  }
  public function 
getEnd()
  {
    return 
$this->end;
  }
  private 
$start$end;
}

class 
NumberSquaredIterator implements Iterator {
  function 
__construct($obj)
  {
    
$this->obj $obj;
  }
  public function 
rewind()
  {
    
$this->cur $this->obj->getStart();
  }
  public function 
key()
  {
    return 
$this->cur;
  }
  public function 
current()
  {
    return 
pow($this->cur2);
  }
  public function 
next()
  {
    
$this->cur++;
  }
  public function 
valid()
  {
    return 
$this->cur <= $this->obj->getEnd();
  }
  private 
$cur;
  private 
$obj;
}
$obj = new NumberSquared(37);
foreach (
$obj as $key => $value) {
  print 
"The square of $key is $value\n";
}

?>

test .... śmiało, śmiało ... zapraszam do notowania :-) i do rejestracji, testować pisanie można w brudnopisie.

 
Nie ma plików na tej stronie. [Wyświetl pliki/formularz]
Komentarze (0). [Dodaj/Wyświetl komentarze]

Informacje zanotowane na tej stronie sa publicznie dostępne. Każdy kto ma ochote może je wykorzystaż w dowolnym celu. Notujac tu coś godzisz sie z tym faktem.

Jeżeli widzisz na tej stronie treść lub kod Twojego autorstwa, na których upublicznianie przeze mnie sie nie godzisz daj mi znać.

Jeżeli uważasz informacje zamieszczone na tej stronie za użyteczne umieść linka do tej strony na własnych stronach. Dzięki temu większa ilość ludzi będzie mogła na tą stronę trafić.

Internetowy katalog stron internetowych