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

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
bas87
Člen | 8
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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).