Bonjour,

Je cherche à appliquer l'expression régulière POSIX fournie dans la RFC 3986 page 50 via une expression PCRE afin d'obtenir les différents composants d'une URL.

http://www.ietf.org/rfc/rfc3986.txt

J'ai créé une classe pour faire cela :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
 
/**
 * The default router has been designed to work closely with the default
 * dispatcher. Both of these classes cannot be extended because they predefine a
 * default strategy for the application if none is provided during bootstrap.
 *
 * The default router implements an observer design pattern, which means that
 * any component implementing the observer interface (like default dispatcher)
 * can be registered into the default router and be notified when the routing
 * process has been done.
 *
 * This component is designed to analyze a request uri and return informations
 * about its different parts to any component that could request it.
 */
final class router extends subject implements strategy
{
    /**
     * Contains the default uri components
     * Example: http://www.ics.uci.edu/pub/ietf/uri/#Related
     *
     * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
     *  12            3  4          5       6  7        8 9
     * 
     * $1 = http:               $4 = www.ics.uci.edu        $7 = <undefined>
     * $2 = http                $5 = /pub/ietf/uri/         $8 = #Related
     * $3 = //www.ics.uci.edu   $6 = <undefined>            $9 = Related
     *
     * For more informations, see http://tools.ietf.org/html/rfc3986#page-50
     */
    public $_components = array();
 
    // Populate the _components list during construction
    public function __construct()
    {
        $pcre = "`^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$`";
        $url = strtolower(array_shift(explode('/',$_SERVER['SERVER_PROTOCOL'])))
             . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        preg_match_all( $pcre, $url, $this->_components );
    }
 
    // Notifies every attached observer
    public function execute()
    {
        $this->notify();
    }
 
    // Return the requested components
    public function __get( $component )
    {
        switch( $component )
        {
            case 'url': return $this->_components[0][0];
            case 'scheme': return $this->_components[2][0];
            case 'authority': return $this->_components[4][0];
            case 'path': return $this->_components[5][0];
            case 'query': return $this->_components[7][0];
            case 'fragment': return $this->_components[9][0];
            case 'components': return $this->_components;
            default: throw new Exception( "property $component not found" );
        }
    }
}
Cette classe semble fonctionner pas trop mal mais je n'arrive pas à obtenir le fragment situé après le # dans l'URL suivante :

http://localhost/index.php?afficher=76519#monfragment

Lorsque j'affiche mon tableau $_components, voici ce qui est retourné :

Array
(
[0] => Array
(
[0] => http://localhost/index.php?afficher=76519
)

[1] => Array
(
[0] => http:
)

[2] => Array
(
[0] => http
)

[3] => Array
(
[0] => //localhost
)

[4] => Array
(
[0] => localhost
)

[5] => Array
(
[0] => /index.php
)

[6] => Array
(
[0] => ?afficher=76519
)

[7] => Array
(
[0] => afficher=76519
)

[8] => Array
(
[0] =>
)

[9] => Array
(
[0] =>
)

)
Il me manque la dernière partie (les entrées 8 et 9 du preg_match_all), quelqu'un saurait-il me dire pourquoi ?