Oppure

Loading
01/04/16 19:24
TheDarkJuster
Buonasera,
sto avendo problemi con l'uso delle espressioni regolari per fare il matching degli URL.

Al momento uso questo codice:
/**
         * Set the routing for a given method/URI pair (or group of URI if regex is used).
         * An example of usage can be:
         * <code>
         * use Gishiki\Core;
         * 
         * Routing::setRoute(Routing::GET, "/user/1058257", function ($params) {
         *      foreach ($params as $param_name => $param_value) {
         *          echo $param_name." => ".$param_value;
         *      }
         * });
         * 
         * //if the framework is installed at https://site.com/ when an user requests
         * //https://site.com/user/5476 the user will see: id => 5476
         * </code>
         * 
         * @param integer $Method one request method chosen from GET, POST, HEAD ecc.... 
         * @param string $URI the URI that will bring to the function execution
         * @param function $function the function executed when the URL is called
         */
        public static function setRoute($Method, $URI, $function) {
            if ((!static::$executed) && (static::getRequestMethod() == $Method)) {
                //this will contain the matched expressions placeholders
                $params = array();

                //detect if regex are involved in the furnished URI
                if (preg_match_all('/{[[:alnum:]]+}/', $URI, $params)) {
                    //this is the regular expression an URL must match to trigger the function execution
                    $URItoBeMatched = $URI;
                    
                    //sobstitute each virtual param with a regex that matches everything
                    foreach ($params as $param_name => $param_value) {
                        $URItoBeMatched = str_replace($param_value, "(.*)", $URItoBeMatched);
                    }
                    
                    $URI_real_params = array();

                    //preg_match_all("@^".$URItoBeMatched."*$@i", static::getRequestURI(), $URI_real_params);
                    preg_match("@^".$URItoBeMatched."*@i", static::getRequestURI(), $URI_real_params);
                    
                    var_dump($URItoBeMatched);
                    var_dump($params);
                    var_dump($URI_real_params);
                    
                } else {
                    //no regex routing: just check if the current request is done to the given routing
                    if (static::getRequestURI() == $URI) {
                        $function();
                        static::$executed = TRUE;
                    }
                }
            }
        }


La descrizione dovrebbe essere abbastanza per capire cosa voglio fare, ma lo rispiego comunque.

dato un URI del tipo: /user/1058257/post/{num}
voglio che vangano matchati tutti gli uri del tipo: /user/X1/post/X2 con X1, X2 qualsiasi serie di caratteri.

Fino a qui non c'è alcun problema: tutti gli uri vengono riconosciuti a dovere.

Tuttavia io voglio di più: voglio generare un array costruito nel seguente modo:
$param = array(
    "id" => X1,
    "post" => X2,
);

Questo sarebbe semplicissimo se il risultato di preg_match non fosse diverso da ciò che mi aspetto:
imposto il routing nel seguente modo: \Gishiki\Core\Routing::setRoute(\Gishiki\Core\Routing::GET, "/user/1058257/post/{post}", function($params) {});

grazie al primo var_dump so che il risultato della prima preg_match è corretto:
array (
 0 => "1058257",
 1 => "{post}",
);


il risultato del secondo è un vero disastro: provando l'URI /user/45/post/60 ottengo:
array (
 0 => '/user/45/post/60',
 1 => '45',
 2 => ''
);


Va bene, passi il fatto che il primo match è ovviamente la stringa intera.....
il secondo elemento dell'array è corretto.....
ma.... io mi aspettavo un '60' come terzo elemento. Perchè ottengo solo '' anche cambiando il 60 con qualsiasi altra cosa?
aaa
02/04/16 15:04
Roby94
Ciao, per semplicità ti mostro solo la regex che adopererei io
^\/user\/([^/]+)\/post\/([^/]+)$

Le preg_match restituiscono dovrebbero sempre (se non mi sto confondendo) come primo gruppo rilevato (pre intenderci lo 0) l'intero matching in quanto per definizione i gruppi delle regex sono enumerati partendo da 1, quindi il risultato non è cosi assurdo.
Con la regex che ho postato sopra identifichi qualsiasi cosa per id tranne gli slash cosi da non avere problemi per ogni sorta di codifica.
Ti consiglierei inoltre questo tool che negli anni si è evoluto diventando uno strumento indispensabile per la formulazione di regex regexr.com/
Spero di essere stato utile.
Ultima modifica effettuata da Roby94 02/04/16 15:04
aaa
02/04/16 19:50
TheDarkJuster
Beh per il momento ho risolto senza regex in maniera abbastanza semplice, quindi mi ritengo soddisfatto, ma grazie comunque del consiglio.
Se dovessero servirmi ancora le regex so cosa fare :heehee:

Grazie dei consigli, appena ho un po di tempo provo la regex per sfizio personale
aaa
03/04/16 0:47
Roby94
Guarda, le regex ti cambiano la vita nel campo dei parser. Tanto da portarti all'odio quando ti trovi su un sistema che non le supporta (vedi microcontrollori a 8bit). Indubbiamente un tassello indispensabile per un buon programmatore general purpose :rofl:
aaa
03/04/16 14:31
TheDarkJuster
Da quel che vedo ereg_match non funziona: la regex funziona solo su regexr.com/, ma non con php.
Ho messo la regex direttamente nel sorgente (non è generata a runtime) quindi non posso averla sbagliata, anche perchè faccio un var_dump ed esce esattamente la query che mi hai dato (con i caratteri di apertura e chiusura)
aaa
03/04/16 15:14
Roby94
Si, dipende dal implementazione se / deve essere preceduto da carattere di escape.
$matches=[];
$subject = "/user/10/post/47";
preg_match("/^\/user\/([^\/]+)\/post\/([^\/]+)$/", $subject, $matches); 
var_dump($matches);
Ultima modifica effettuata da Roby94 03/04/16 15:19
aaa