Type Hinting v PHP, má to řešit framework?

- bas87
 - Člen | 8
 
Zajímali by mě vaše názory na Type Hinting v PHP.
V případech kdy chci aby byl parametr metody integer a když není, tak se
vyhodila nějaká chyba, případně výjimka, tak standardně přes if
(is_integer()) v těle metody je to velmi otravné.
Mnohem elegantnější by byl zápis public function
nejaka_funkce(integer $promena) {}.
Za normální okolností toto v PHP nelze napsat, ale některé frameworky toto
různými postupy obchází.
Například:
<?php
define('TYPEHINT_PCRE'              ,'/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');
class Typehint
{
    private static $Typehints = array(
        'boolean'   => 'is_bool',
        'integer'   => 'is_int',
        'float'     => 'is_float',
        'string'    => 'is_string',
        'resrouce'  => 'is_resource'
    );
    private function __Constrct() {}
    public static function initializeHandler()
    {
        set_error_handler('Typehint::handleTypehint');
        return TRUE;
    }
    private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue)
    {
        foreach ($ThBackTrace as $ThTrace)
        {
            // Match the function; Note we could do more defensive error checking.
            if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction)
            {
                $ThArgValue = $ThTrace['args'][$ThArgIndex - 1];
                return TRUE;
            }
        }
        return FALSE;
    }
    public static function handleTypehint($ErrLevel, $ErrMessage)
    {
        if ($ErrLevel == E_RECOVERABLE_ERROR)
        {
            if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches))
            {
                list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;
                if (isset(self::$Typehints[$ThHint]))
                {
                    $ThBacktrace = debug_backtrace();
                    $ThArgValue  = NULL;
                    if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue))
                    {
                        if (call_user_func(self::$Typehints[$ThHint], $ThArgValue))
                        {
                            return TRUE;
                        }
                    }
                }
            }
        }
        return FALSE;
    }
}
Typehint::initializeHandler();
function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }
// Example
teststring('ahoj...');
teststring(999);  // Chyba
Jaký je váš názor na takový to přístup?
Používáte to někdo ?

- Mikulas Dite
 - Člen | 756
 
Tohle v php nemá cenu řešit. Jediný důvod je právě vyžadování int, ten se dá ale získat i ze stringu. Už jsem se nad tím jednou zamýšlel a dospěl jsem k tomu, že to nepoužívám zdaleka tak často. Intval a jedna exception jsou dostatečně krátké a píší se dobře, type hint by nebyl v php intuitivní.
Edit: nicméně ten hack je super kód (což vůbec neznamená, že použití je taky dobré). Zajímalo by mě, jak se to bude bít s nette, které se řídí hlavně pomocí výjimek a handlerů.
Editoval Mikulas Dite (15. 3. 2011 16:16)

- bas87
 - Člen | 8
 
A já zase ověřování zda se jedná o int používám velmi často a
zápis nějaké výjimky mi přijde velmi otravný. Velmi pěkné by bylo, kdyby
se v případě nedodržení datového typu vyhodila výjimka.
Toto mi v PHP velmi chybí. Snad minulý rok se mluvilo o tom, že toto snad
má být nativně v bájném PHP6.
Řekněme, že by jsme se shodli na tom, že to užitečné je. Je filozoficky správné si toto do současné verze php přidat?
Editoval bas87 (15. 3. 2011 17:18)

- Filip Procházka
 - Moderator | 4668
 
Nějaký nenásilný Type Hint by se hodil, tohle je ovšem dost brutální hack :) v momentě kdy nějaký chytrák vytvoří třídu string, tak to přestane fungovat :)

- bas87
 - Člen | 8
 
HosipLan napsal(a):
Nějaký nenásilný Type Hint by se hodil, tohle je ovšem dost brutální hack :) v momentě kdy nějaký chytrák vytvoří třídu string, tak to přestane fungovat :)
to by šlo řešit přes class_exists…ono tam je ještě víc
záludnosti…
viděl jsem aj modul pro php, který toto řešil, ale víc se mi líbí
řešení přes error handler

- Petr Motejlek
 - Člen | 293
 
Až vyjde bájné PHP6, tak to nikdo nebude používat, protože už to bude tak blízko Javě, že na ni radši všichni vývojáři přejdou :D:D:D.

- jtousek
 - Člen | 951
 
V PHP to nemá smysl řešit. Něco takového má smysl používat až když bys to používal prakticky všude – u všech fcí a metod. A kdyby se volání každé funkce prohánělo něčím podobným, celou aplikaci by to dost nepříjemně zpomalilo. Nebo to funguje jinak?
V Nette má smysl řešit akorát validaci parametrů komponent o které se na fóru už nějakou dobu mluví a je už víceméně implementovaná. Tahle validace funguje podle anotací, což je dostačující.

- Filip Procházka
 - Moderator | 4668
 
Stejně jsou ty type hinty a validace parametrů zbytečné :) Dokud to nebude podporovat jazyk, tak to akorát zpomaluje a lze to vždy dyštak napsat „ručně“, ale stejně to není potřeba…

- Patrik Votoček
 - Člen | 2221
 
Souhlas tohle nemá význam hackovat. Protože to nejde doplnit/dodělat čistě. Před pár měsíci se tohle hodně diskutovalo jako budoucí část přímo PHP snad už verze 5.4 (od té doby nějak nemám čas to sledovat).