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";
}
?>