Class PhpHex2Str

Mammouth du PHP | 985 Messages

21 mars 2010, 09:24

Une class pour décoder les caractères hexadécimaux dans les chaines. :wink:
(La fonction x_hex2str() est une adaptation d'une fonction déjà existante sur le net du nom de hex2str().)
<?php
class PhpHex2Str
{
    private $strings;

    private function x_hex2str($hex) {
        $hex = substr($hex[0], 1);
        $str = '';
        for($i=0;$i < strlen($hex);$i+=2) {
            $str.=chr(hexdec(substr($hex,$i,2)));
        }
        return $str;
    }

    public function decode($strings = null) {
        $this->strings = (string) $strings;
        return preg_replace_callback('#\%[a-zA-Z0-9]{2}#', 'x_hex2str', $this->strings);
    }
}

// Exemple
$strings = 'a %20 b%0A h %27 h %23';

$obj = new PhpHex2Str;
$strings = $obj->decode($strings);
var_dump($strings);
?>
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 5462 Messages

21 mars 2010, 19:44

hello,
marche pas ta fonction, tu peux pas faire un callback avec un fonction qui n'existe pas dans le global (ici : 'x_hex2str'), comme elle est dans ta classe il faut faire :
preg_replace_callback('#\%[a-zA-Z0-9]{2}#', array(get_class($this), 'x_hex2str'), $this->strings);
après je vois pas bien l'intérêt de boucler, puisque que ton preg ne prend que 2 caractères, ducoup juste ca
private function x_hex2str($hex) {
    $hex = hexdec(substr($hex[0], 1));
    return chr($hex);
}
et sinon rawurldecode ca fait la même chose...
rawurldecode(a %20 b%0A h %27 h %23);
//string(14) "a   b
// h ' h #"

Mammouth du PHP | 985 Messages

21 mars 2010, 20:05

Oui je m'étais trompé de class, j'avais mis la class test qui était contenue dans le fichier test qui contenait lui même la fonction en dehors de la class.

Sinon pour le reste, décompresse tu vas nous faire une syncope :roll:
<?php
class PhpHex2Str
{
    private $strings;

    private function x_hex2str($hex) {
        $hex = substr($hex[0], 1);
        $str = '';
        for($i=0;$i < strlen($hex);$i+=2) {
            $str.=chr(hexdec(substr($hex,$i,2)));
        }
        return $str;
    }

    public function decode($strings = null) {
        $this->strings = (string) $strings;
        return preg_replace_callback('#\%[a-zA-Z0-9]{2}#', array(get_class($this), 'x_hex2str'), $this->strings);
    }
}

// Exemple
$obj = new PhpHex2Str;

$strings = $obj->decode($strings);
var_dump($strings);
?>
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 5462 Messages

21 mars 2010, 20:23

Sinon pour le reste, décompresse tu vas nous faire une syncope :roll:
pourquoi j'ai tort ?

Mammouth du PHP | 985 Messages

21 mars 2010, 20:31

Je prends soin de ta santé Steal, c'est tout :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Mammouth du PHP | 985 Messages

21 mars 2010, 22:08

On pourrait faire plus simplement, comme ceci:
<?php
class PhpHex2Str
{
    private $strings;

    private static function x_hex2str($hex) {
        $hex = substr($hex[0], 1);
        $str = '';
        for($i=0;$i < strlen($hex);$i+=2) {
            $str.=chr(hexdec(substr($hex,$i,2)));
        }
        return $str;
    }

    public function decode($strings = null) {
        $this->strings = (string) $strings;
        return preg_replace_callback('#\%[a-zA-Z0-9]{2}#', 'PhpHex2Str::x_hex2str', $this->strings);
    }
}

// Exemple
$obj = new PhpHex2Str;

$strings = $obj->decode($strings);
var_dump($strings);
?>
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 5462 Messages

21 mars 2010, 22:27

plus simple non mais c'est une autre approche, par contre utilise "self" plutôt que "PhpHex2Str" :
self::x_hex2str

:wink:

Mammouth du PHP | 985 Messages

21 mars 2010, 22:31

J'insiste par plus simple, car on utilise deux fonctions de moins, et cela me parait plus propre et d'ailleurs je pense même conseillé dans ce contexte.

De plus le self, à ce que j'ai compris, n'est pas conseillé ici.

When you use preg_replace_callback in a class and have the callback function as a private method of that class, you need to set the callback function name like className::CallBack.
self::CallBack does not work and returns an error:
"Cannot call method self::CallBack() or method does not exist"!


Pas tout à fait le même contexte peut-être, mais comme ça au moins, on évite les erreurs par la suite si on modifie la class...
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

21 mars 2010, 23:32

Pourquoi la méthode decode() ne serait elle pas elle même statique ?
Ou, pour t'aider à répondre à cette question, quels sont les intérêts d'utiliser une instance de la classe pour appeler la méthode ?

Je pense que l'attribut "strings" n'est pas nécessaire.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 985 Messages

21 mars 2010, 23:43

Car au départ je n'avais pas pensé devoir mettre l'autre fonction en statique.
Puis ensuite: car pour le moment mes connaissances en programmation objet en php sont limités, et que je n'ai pas encore véritablement poussé la question du statique.

Sinon, dès que j'ai mis une des fonctions en statique, je me suis posé la même question ensuite, car en effet les deux fonctions peuvent être utilisées, si je modifie un peu, séparemment pour différents besoins...
Et cela économisera l'obligation d'instancier la class...

Pour le private string, c'est vrai aussi, une habitude que j'ai pris surement.

En fait l'avantage de la class est juste de réunir les deux fonctions en un seul bloc.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

21 mars 2010, 23:54

Sur le fait d'utiliser une classe, j'abonde, c'est une bonne pratique pour rassembler les fonctions au sein d'une entité.

Mais, pour faire du développement OO, et plus des classes, il faut se poser quelques questions :
- la visibilité de mes méthodes : en ce qui me concerne, je met par défaut en protected, puis je passe public si elle doit être accessible, et private si je veux bloquer l'appel direct, même depuis les filles
- statique ou pas : est-que disposer de l'instance de la classe est nécessaire ? tant que c'est non => statique
- attribut : est-ce que l'attribut que je vais créer est une composante de l'objet, et est-ce qu'il est nécessaire de la stocker dans l'objet ?

En se posant ces questions, tu arriveras à des conclusions logiques qui t'aiderons fortement lors de la construction de tes classes
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Mammouth du PHP | 985 Messages

21 mars 2010, 23:57

Ok oui je comprends ce que tu veux dire :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
ViPHP | 5462 Messages

22 mars 2010, 00:44

J'insiste par plus simple, car on utilise deux fonctions de moins, et cela me parait plus propre et d'ailleurs je pense même conseillé dans ce contexte.

De plus le self, à ce que j'ai compris, n'est pas conseillé ici.

When you use preg_replace_callback in a class and have the callback function as a private method of that class, you need to set the callback function name like className::CallBack.
self::CallBack does not work and returns an error:
"Cannot call method self::CallBack() or method does not exist"!


Pas tout à fait le même contexte peut-être, mais comme ça au moins, on évite les erreurs par la suite si on modifie la class...
attention au commentaire de la doc, je vois que ta lu ca ici or ni la version ni la config n'est renseigné test toi même le code (chez moi l'exemple marche parfaitement) n'oublie pas que php 5.3 a changer des choses ce coté aussi, et justement si tu modifies le nom de la class tu voir devoir allé modifier ton code a chaque fois :wink:

Mammouth du PHP | 985 Messages

22 mars 2010, 02:08

Ce n'est pas le fond du problème, le self c'est juste un détail, le fond c'est qu'il fallait l'utiliser en static simplement.

Puis finalement, ce n'est pas du tout un détail, j'ai testé ton conseil avec le self:

[22-Mar-2010 00:44:44] PHP Fatal error: Cannot call method self::x_hex2str() or method does not exist in /***/***.php on line 20

Erreur fatale en php 5.2.6

Donc, je te conseille à mon tour, dans ce contexte particulier, de ne pas utiliser self au risque de rendre ta class non portable pour une version de php inférieur à 5.3.

Ps:
Par contre je confirme que cela fonctionne avec PHP 5.3.2 et je confirme aussi que __toString() doit être public en PHP 5.3.2 (sinon Warning).
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Mammouth du PHP | 985 Messages

22 mars 2010, 06:28

<?php
class PhpHex2Str
{
    public static function x_hex2str($hex) {
        if (is_array($hex)) $hex = substr($hex[0], 1);
        $hex = (string) $hex;
        $str = '';
        for($i=0;$i < strlen($hex);$i+=2) {
            $str.=chr(hexdec(substr($hex,$i,2)));
        }
        return $str;
    }

    public static function decode($strings = null) {
        $strings = (string) $strings;
        return preg_replace_callback('#\%[a-zA-Z0-9]{2}#', 'PhpHex2Str::x_hex2str', $strings);
    }
}

// Exemple 1
$strings = 'a %20 b%0A h %27 h %23';
print PhpHex2Str::decode($strings);

// Exemple 2
$hex = '2723';
print PhpHex2Str::x_hex2str($hex);
?>
Bon voilà la nouvelle version.
jai bien cru devoir obligatoirement instancier la class pour ajouter une variable objet de vérification...
je voulais utiliser le principe du static pour les deux fonctions.
La fonction is_array() ma finalement, encore une fois, sauvé la mise.

(Pour info: j'ai testé le self vue que les 2 fonctions étaient public et statiques, mais cela cause une erreur fatale encore en dessous de Php 5.3)
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.