22 lis
PHP – co robić gdy musimy wymusić typy
Jak wiadomo PHPe nie jest językiem o silnym typowaniu. W wyniku tego do funkcji możemy przesyłać praktycznie wszystko. Często brak wstępnego określania typu parametrów w deskryptorze metod/funkcji pogarsza jakość i czytelność kodu. Osobiście czytając czyjś kod lubię wiedzieć co przyjmuje funkcja/metoda tzn. jaki konkretny typ parametrów one przyjmują. Dość często powstaje różnego rodzaju pomieszania typów, czyli wchodzi string potem przemieniany jest na inta a na wyjściu na dodatek możemy dostać obiekt… Ponadto w PHPe pomimo bogatej proceduralnej biblioteki do obsługi łańcuchów znaków nie istnieje jej wersja obiektowa, a szkoda… Z tego też względu pokusiłem opisać szkicowe rozwiązanie umożliwiające połączenie przyjemnego z pożytecznym tj. utworzenie klasy osłonowej na typ String ułatwiającej operację na obiektach tego typu. Rozwiązanie to daje:
1. Możliwość pośredniego rzutowania na dobrze zdefiniowany typ String
2. Możliwość sprawdzania typu String przez interpreter, tego czy przekazujemy prawidłowy parametr do funkcji/metody
3. Ustala konwencję w kodowaniu i aplikacji.
W miarę możliwość w następnych dniach postaram się opisać prezentowane rozwiązanie. Póki co ograniczę się do przedstawienia samego kodu.
_string = (string) $arg; } public function length() { return mb_strlen($this->_string); } public static function toString($arg) { return new String($arg); } public function getString() { return $this->_string; } public function setString($arg) { $this->_string = (string) $arg; } public function __toString() { return $this->_string; } } } /** * Przestrzeń nazw dla różnego rodzaju analizatorów. * * @author Marcin M. * */ namespace AnalyzerBase { /** * Abstarakcyjna klasa analizatora. * * @author Marcin M. * */ abstract class Analyzer { } } /** * Przestrzeń nazw dla analizatora Tekstu. * * @author Marcin M. * */ namespace AnalyzerText { use AnalyzerBase; use String; /** * Analizator tekstu * * @author Marcin M. * */ class Analyzer extends AnalyzerBase\Analyzer { /** * Pobranie długości analizowanego tekstu przy wykorzystaniu klasy String * * @tutorial Obiekty przekazywane są do funkcji i metod przez referencję * * @param String\String $arg * * @return int */ public function length(String\String $arg) { return (int) $arg->length(); } /** * Pobranie długości analizowanego tekstu przy wykorzystaniu klasy i mechanizmów Analizatora * * @tutorial Obiekty przekazywane są do funkcji i metod przez referencję * * @param String\String $arg * * @return int */ public function size(String\String $arg) { return (int) mb_strlen($arg); } /** * Tagowanie wybranych części tekstu * * @param String\String $arg * @param String\String $tag * * @return void */ public function addTag(String\String $arg, String\String $tag) { $openTag = '<'.$tag.'>'; $closeTag = ''.$tag.'>'; $arg->setString($openTag.$arg->getString().$closeTag); } } } /** * Aplikacja z przypadkami testowymi */ namespace { $myString = new String\String('My default string'); echo "Badany string to: " . $myString; echo "\n"; echo "Długośc badanego stringu to: " . $myString->length(); echo "\n"; echo "Rzutowanie statyczne na typ string: " . $myNewString = String\String::toString(567); echo "\n"; echo "Badany rzutowany string to: " . $myNewString; echo "\n"; echo "Długośc badanego rzutownego stringu to: " . $myNewString->length(); echo "\n"; $textAnalyzer = new AnalyzerText\Analyzer(); echo 'Długośc analizowanego tekstu za pomocą Analyzer::length() to: ' . $textAnalyzer->length($myString) . ' znaków'; echo "\n"; echo 'Długośc analizowanego tekstu za pomocą Analyzer::size() to: ' . $textAnalyzer->size($myString) . ' znaków'; echo "\n"; echo 'Długośc analizowanego rzutowanego tekstu za pomocą Analyzer::length() to: ' . $textAnalyzer->length($myNewString) . ' znaków'; echo "\n"; echo 'Długośc analizowanego rzutowanego tekstu za pomocą Analyzer::size() to: ' . $textAnalyzer->size($myNewString) . ' znaków'; echo "\n"; echo 'Operacja przekazywanie obiektu typu String do analizy. Długośc tekstu to: ' . $textAnalyzer->size(String\String::toString('Nowy string')) . ' ' . $textAnalyzer->length(new String\String('Nowy string')) . ' ' . String\String::toString('Nowy string')->length(); echo "\n"; echo 'Test referencji: '; echo "\n"; echo 'String przed zmianą: '. $noTag = new String\String('Jestem stringiem bez tagu na końcu'); echo "\n"; echo $noTag; echo "\n"; echo 'String po zmianeie dodanie tagu `koniec_zdania`: '; $textAnalyzer->addTag($noTag, String\String::toString('koniec_zdania')); echo "\n"; echo $noTag; echo "\n"; echo 'Operacja nie powiedzie się, musimy dysponować obiektem typu String ' . $textAnalyzer->size('Nowy string') . ' ' . $textAnalyzer->length('Nowy string'); echo "\n"; } ?>
Skomentuj ten wpis