PROJET AUTOBLOG


Tiger-222

Site original : Tiger-222

⇐ retour index

PHP : is_file vs file_exists

lundi 14 octobre 2013 à 17:32
is_file, comme la documentation l'indique, vérifie si le fichier est un véritable fichier, tandis que file_exists vérifie si un fichier ou un dossier existe. À savoir que ces deux fonctions utilisent un système de cache, elles partent donc sur un pied d'égalité.

Les sources


Rien de mieux que le retour aux sources pour voir les entrailles de ces deux fonctions. Il s'avère qu'elles utilisent la même function en interne, seules les routines de vérification diffèrent.

Ci-dessous, le pseudo code très simplifié du processus de vérification :
function php_stat($fichier)
{
'file_exists'
↳ virtual_file_ex($fichier)
↳ virtual_access($fichier)
'Windows'
↳ tsrm_win32_access($fichier)
↳ return access($fichier)
'Autres systèmes'
↳ return access($fichier)
↳ return _php_stream_stat_path($fichier) == FALSE
'is_file'
↳ _php_stream_stat_path($fichier)
↳ return $fichier.st_mode == S_IFREG
}

Pour les curieux, voici les sources des fonctions :
Au premier abor, ça semble clair comme de l'eau de roche, file_exists() nécessite bien plus d'opérations à effectuer. Cependant, _php_stream_stat_path() est lourde puisqu'elle récupère toutes les informations sur un fichier/dossier (appelé inode) : volume, numéro d'inode, droit d'accès à l'inode, nombre de liens, userid du propriétaire, groupid du propriétaire, type du volume, si le volume est une inode, taille en octets, date de dernier accès (Unix timestamp), date de dernière modification (Unix timestamp), date de dernier changement d'inode (Unix timestamp), taille de bloc et le nombre de blocs de 512 octets alloués.

Il faudra attendre de voir le résultat des tests pour se faire une meilleure idée.


Une meilleure alternative ?


Dans ce commentaire, DeyV laisse à penser que stream_resolve_include_path serait une bonne alternative à file_exists(). À priori, cette fonction utiliserait aussi le système de cache.
Great alternative to file_exists() is stream_resolve_include_path() -- DeyV
Toujours d'après les sources, le pseudo code suivant en ressort :
function stream_resolve_include_path($fichier)
{
zend_resolve_path($fichier)
↳ php_resolve_path_for_zend($fichier)
↳ php_resolve_path($fichier)
↳ tsrm_realpath($fichier)
↳ return estrdup($fichier)
}

Pour les curieux, le détail de chaque fonction :
Notez que le fait d'utiliser des chemins absolus permet un gain non négligeable.


Les tests


Configuration de la machine de test


Le benchmark


Deux types de tests : un réaliste où on teste la présence de fichiers différents, et un autre moins parlant dans lequel le même fichier est testé 1 000 000 de fois.
Pour le test réaliste, j'ai créé un dossier test qui contient 1 000 000 fichiers (le premier fichier s'appelant 0 et le dernier 999999).
D'après le script qui permet de lancer et chronométrer les tests, le graphique suivant en résulte :



Observations



Historique


MàJ du 2013-10-23 : ajout des explications avec les sources PHP
MàJ du 2013-10-25 : Une meilleure alternative ?
MàJ du 2013-10-27 : ajout de tests plus réalistes et étoffement des informations
MàJ du 2013-10-28 : ajout du script de tests pour ne pas trop encombrer la page

Shaarlimages reloaded !

vendredi 20 septembre 2013 à 03:57
Shaarlimages.net

Shaarlimages.net a subi des débuts assez chaotiques, j'avoue, mais il faut savoir vivre dans le danger !
Pour vous en mettre plein la vue, jettez un œil à cette image, et utilisez les flèches gauche & droite pour aller à la précendente & suivante... ❤
Bref, suite à de nombreux retours, tous positifs, voici quelques informations.


Changements


Étant donné que la base était assez légère, il n'y a pas grand chose de changé, hormis la couleur de fond de la galerie qui est passée à #EEEEEE.
Le système de la galerie a été entièrement réécrit en JS/CSS/HTML, plus de PHP. Ça permettra d'avoir des galeries sur clefs USB ou des serveurs sans PHP (ça existe encore ?). D'ailleurs, pour ceux qui veulent s'approprier juste le système, reportez-vous au dépôt Galinear (je le mettrai à jour une fois que j'aurai quelque chose de plus facile à intégrer).
MàJ du 2013-09-23 : utilisation de la liste des shaarlis de Shaarli Flux River, plus complète.
MàJ du 2013-09-26 : amélioration notable lors de la récupération des liens et création de thumbnails pour alléger les pages.
MàJ du 2013-09-27 : refonte du code, tout est paramétrable dans inc/Config.php.


Nouveautés


Ou plutôt devrais-je dire : fonctionnalités de base que je n'avais pas encore implémentées...

J'ai mis le paquet sur la possibilité de personnaliser l'affichage. Les paramètres par défaut peuvent être modifiés soit en passant par l'URL, soit en utilisant le petit panneau en haut à gauche, qui utilise les cookies pour que ça soit permanent. Les différents paramètres sont :

Un gros travail a été fait pour rendre le code plus agréable et facile à étudier. Je me suis pas mal inspiré des projets KrISS feed (vraiment propre, c'est du joli !) et Shaarli Flux River (pour la classe RSS).


Futur


Ketluts a proposé d'utiliser un fond ambiligth plutôt qu'une couleur moyenne : je regarderai ça plus tard, ça pourra être une option d'affichage, en tout cas, ça rend bien. (OK, MàJ du 2013-09-28, d'autres informations sur cette page : Ambilight для тэга video)

La prise en compte des évènements de toucher pour les smartphones (faire glisser un doigt pour changer d'image ou de page). (OK, MàJ du 2013-09-26)

Et la mise en place d'une API pour faire toute sorte de recherches.

Sur certains site web, l'accès est difficile. Par exemple pour le Shaarli de Sam Ganegie, j'ai plus souvent cette erreur que le flux : Access denied | sameganegie.biz used CloudFlare to restrict access. Sur celui du Warrior du Dimanche, idem, c'est à la roulette russe, j'ai une restriction comme quoi mon adresse IP est cataloguée en SPAM. Il faut trouver une parade.


Appel de détresse


Avec tous les services qui se font autour de shaarli (Flux RSS des Shaarlis -- 102 liens, Shaarlo -- 105 liens, Shaarli Flux River -- 111 liens et ShaarliTV), il serait fort intéressant d'avoir un seul fichier OPML contenant les différents shaarlis actifs. J'utilise celui de Shaarlo, mais il y a déjà deux flux HS. Ça vous tente de regrouper vos URL vers Shaarlo ? Ou autre part, je ne suis pas casse-pied. ☺

MàJ du 2013-09-26 : mon appel a été entendu ! Voici une 1ère réponse et des idées pour un annuaire de Shaarlis (n'hésitez pas à participer, tous les avis sont bons à prendre).

Shaarlimages reloaded !

vendredi 20 septembre 2013 à 01:57
Shaarlimages.net

Shaarlimages.net a subi des débuts assez chaotiques, j'avoue, mais il faut savoir vivre dans le danger !
Pour vous en mettre plein la vue, jettez un œil à cette image, et utilisez les flèches gauche & droite pour aller à la précendente & suivante... ❤
Bref, suite à de nombreux retours, tous positifs, voici quelques informations.


Changements


Étant donné que la base était assez légère, il n'y a pas grand chose de changé, hormis la couleur de fond de la galerie qui est passée à #EEEEEE.
Le système de la galerie a été entièrement réécrit en JS/CSS/HTML, plus de PHP. Ça permettra d'avoir des galeries sur clefs USB ou des serveurs sans PHP (ça existe encore ?). D'ailleurs, pour ceux qui veulent s'approprier juste le système, reportez-vous au dépôt Galinear (je le mettrai à jour une fois que j'aurai quelque chose de plus facile à intégrer).
MàJ du 2013-09-23 : utilisation de la liste des shaarlis de Shaarli Flux River, plus complète.
MàJ du 2013-09-26 : amélioration notable lors de la récupération des liens et création de thumbnails pour alléger les pages.
MàJ du 2013-09-27 : refonte du code, tout est paramétrable dans inc/Config.php.


Nouveautés


Ou plutôt devrais-je dire : fonctionnalités de base que je n'avais pas encore implémentées...

J'ai mis le paquet sur la possibilité de personnaliser l'affichage. Les paramètres par défaut peuvent être modifiés soit en passant par l'URL, soit en utilisant le petit panneau en haut à gauche, qui utilise les cookies pour que ça soit permanent. Les différents paramètres sont :

Un gros travail a été fait pour rendre le code plus agréable et facile à étudier. Je me suis pas mal inspiré des projets KrISS feed (vraiment propre, c'est du joli !) et Shaarli Flux River (pour la classe RSS).


Futur


Ketluts a proposé d'utiliser un fond ambiligth plutôt qu'une couleur moyenne : je regarderai ça plus tard, ça pourra être une option d'affichage, en tout cas, ça rend bien. (OK, MàJ du 2013-09-28, d'autres informations sur cette page : Ambilight для тэга video)

La prise en compte des évènements de toucher pour les smartphones (faire glisser un doigt pour changer d'image ou de page). (OK, MàJ du 2013-09-26)

Et la mise en place d'une API pour faire toute sorte de recherches.

Sur certains site web, l'accès est difficile. Par exemple pour le Shaarli de Sam Ganegie, j'ai plus souvent cette erreur que le flux : Access denied | sameganegie.biz used CloudFlare to restrict access. Sur celui du Warrior du Dimanche, idem, c'est à la roulette russe, j'ai une restriction comme quoi mon adresse IP est cataloguée en SPAM. Il faut trouver une parade.


Appel de détresse


Avec tous les services qui se font autour de shaarli (Flux RSS des Shaarlis -- 102 liens, Shaarlo -- 105 liens, Shaarli Flux River -- 111 liens et ShaarliTV), il serait fort intéressant d'avoir un seul fichier OPML contenant les différents shaarlis actifs. J'utilise celui de Shaarlo, mais il y a déjà deux flux HS. Ça vous tente de regrouper vos URL vers Shaarlo ? Ou autre part, je ne suis pas casse-pied. ☺

MàJ du 2013-09-26 : mon appel a été entendu ! Voici une 1ère réponse et des idées pour un annuaire de Shaarlis (n'hésitez pas à participer, tous les avis sont bons à prendre).

Shaarlimages.net

vendredi 13 septembre 2013 à 01:23
shaarlimages.jpg

Suite à cette requête, je me suis penché sur le sujet. Après quelques recherches et bidouillages de codes, je vous présente Shaarlimages ! Pour l'occasion, j'ai réservé le nom de domaine, mais si quelqu'un d'autre le veut, je pourrai le céder facilement ☺.

Le but était d'avoir une galerie qui soit d'un niveau proche de celle de Chromatic.io. Je me suis imposé de ne pas utiliser de bibliothèques tierces telles que jQuery ou Prototype ; c'est du donc du javascript natif. Les sources de chromatic.io étant relativement obfusquées (quelle merde ce cloud d'Amazon...), je me suis largement inspiré du projet de Jakob Holmelund : fitpicjs, un grand merci à ce brave homme !


La démo


C'est sur Shaarlimages.net que ça se passe. Il est possible de filtrer par date en ajoutant à l'URL le paramètre d : ?d=aaaammdd, exemple avec la journée du 8 août 2013.

Par défaut, si le tag NSFW (Not Safe for Work) est trouvé dans la catégorie, le titre ou la description, l'image sera alors presque invisible. En cliquant dessus, par contre, l'image ne sera pas filtrée. Il est possible de désactiver ce filtrage en passe le paramètre $CONFIG['show_nsfw'] à true.

Je me sers du fichier d'export de shaarli.fr pour récupérer la liste des shaarlis à parser, donc si vous souhaitez ajouter le vôtre, envoyez un p'tit mot.


Téléchargement


Le code du site entier est sur GitHub, faites-vous plaisir !


Plus d'informations ?


La galerie utilise le système de partition linéaire, c'est-à-dire perdre le moins d'espace possible. Les images sont redimensionnées pour qu'une quantité correcte soit affichée par ligne, et ce de façon agréable visuellement ☂. L'article The algorithm for a perfectly balanced photo gallery (en anglais) explique un peu plus en détails le principe.
Lors d'un clic sur une image, l'affichage est important : l'image prend le maximum d'espace sur l'écran et la couleur de fond est adaptée à chacune d'entre elles. J'utilise une fonction PHP pour déterminer la couleur dominante moyenne :

function docolav($fichier) {
list($width, $height, $type) = getimagesize($fichier);
if ( $type == 2 ) { // jpeg
$img = imagecreatefromjpeg($fichier);
} elseif ( $type == 3 ) { // png
$img = imagecreatefrompng($fichier);
} else {
return NULL;
}

// http://stackoverflow.com/questions/6962814/average-of-rgb-color-of-image
$tmp_img = ImageCreateTrueColor(1, 1);
ImageCopyResampled($tmp_img, $img, 0, 0, 0, 0, 1, 1, $width, $height);
$rgb = ImageColorAt($tmp_img, 0, 0);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

unset($rgb);
imagedestroy($tmp_img);
imagedestroy($img);
return sprintf('%02X%02X%02X', $r, $g, $b);
}

Ce code est relativement rapide (bien plus que ma version C++ d'ailleurs...), on demande à redimensionner l'image à 1x1 pixel, tout en gardant l'échantillonnage des couleurs : donc calcul de la couleur moyenne dominante pour savoir quelle sera la couleur de ce seul pixel. Bien pensé et diablement plus efficace que parcourir tous les pixels à la main.

De plus, si vous avez compris le code, vous aurez requarqué que seuls les formats d'image JPEG et PNG sont pris en compte. D'autres seront à venir suivant la demande (hormis pour les images animées).


Pour les développeurs


Avant tout, sachez que ce n'est pas la mer à boire : 3.2 ko (CSS) + 3.1 ko (JS) = 6.3 ko !

Ensuite, Shaarlimages est un exemple, mais pour ceux qui veulent utiliser le même système ailleurs, voici comment faire. Dans votre code, il faut définir un conteneur avec l'ID image-container. Dans ce conteneur, chaque image doit être encadrée dans une figure. Puis incluez le code javascript en bas de page, ça devrait être bon.

Exemple :
<div id="image-container">
	<figure>
<a href="./media/00a3687b." data-original-source="https://tiger-222.fr/"><img src="./media/084d514f.image.jpg" data-original-source="https://tiger-222.fr/images/image.jpg"></a>
</figure>

<!-- Un exemple avec une image sensible (NSFW) -->
<figure data="nsfw">
<a href="./media/00a3687b." data-original-source="https://tiger-222.fr/"><img src="./media/df2ddecb.image-trop-sexy.jpg" data-original-source="https://tiger-222.fr/images/image-trop-sexy.jpg"></a>
</figure>
</div>

<script async src="https://tiger-222.fr/linear-partition.min.js"></script>
Pensez aussi à include le fichier CSS.


Améliorations possibles


Dans l'immédiat, la couleur de fond pour chaque image est calculée (couleur moyenne dominante) et une image est ajoutée par dessus pour le grain. Bien que ça ne rende pas trop mal, il faudrait revoir le mécanisme pour se rapprocher un peu plus de cette galerie (qui utilise des images).

Éventuellement, trouver un service en ligne, ou un code PHP, permettant de compresser les images (progressif pour le JPEG, et optimisations générales).

Pour le reste, libre à vous de forker, bidouiller et proposer des patches ☺

Shaarlimages.net

jeudi 12 septembre 2013 à 23:23
shaarlimages.jpg

Suite à cette requête, je me suis penché sur le sujet. Après quelques recherches et bidouillages de codes, je vous présente Shaarlimages ! Pour l'occasion, j'ai réservé le nom de domaine, mais si quelqu'un d'autre le veut, je pourrai le céder facilement ☺.

Le but était d'avoir une galerie qui soit d'un niveau proche de celle de Chromatic.io. Je me suis imposé de ne pas utiliser de bibliothèques tierces telles que jQuery ou Prototype ; c'est du donc du javascript natif. Les sources de chromatic.io étant relativement obfusquées (quelle merde ce cloud d'Amazon...), je me suis largement inspiré du projet de Jakob Holmelund : fitpicjs, un grand merci à ce brave homme !


La démo


C'est sur Shaarlimages.net que ça se passe. Il est possible de filtrer par date en ajoutant à l'URL le paramètre d : ?d=aaaammdd, exemple avec la journée du 8 août 2013.

Par défaut, si le tag NSFW (Not Safe for Work) est trouvé dans la catégorie, le titre ou la description, l'image sera alors presque invisible. En cliquant dessus, par contre, l'image ne sera pas filtrée. Il est possible de désactiver ce filtrage en passe le paramètre $CONFIG['show_nsfw'] à true.

Je me sers du fichier d'export de shaarli.fr pour récupérer la liste des shaarlis à parser, donc si vous souhaitez ajouter le vôtre, envoyez un p'tit mot.


Téléchargement


Le code du site entier est sur GitHub, faites-vous plaisir !


Plus d'informations ?


La galerie utilise le système de partition linéaire, c'est-à-dire perdre le moins d'espace possible. Les images sont redimensionnées pour qu'une quantité correcte soit affichée par ligne, et ce de façon agréable visuellement ☂. L'article The algorithm for a perfectly balanced photo gallery (en anglais) explique un peu plus en détails le principe.
Lors d'un clic sur une image, l'affichage est important : l'image prend le maximum d'espace sur l'écran et la couleur de fond est adaptée à chacune d'entre elles. J'utilise une fonction PHP pour déterminer la couleur dominante moyenne :

function docolav($fichier) {
list($width, $height, $type) = getimagesize($fichier);
if ( $type == 2 ) { // jpeg
$img = imagecreatefromjpeg($fichier);
} elseif ( $type == 3 ) { // png
$img = imagecreatefrompng($fichier);
} else {
return NULL;
}

// http://stackoverflow.com/questions/6962814/average-of-rgb-color-of-image
$tmp_img = ImageCreateTrueColor(1, 1);
ImageCopyResampled($tmp_img, $img, 0, 0, 0, 0, 1, 1, $width, $height);
$rgb = ImageColorAt($tmp_img, 0, 0);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

unset($rgb);
imagedestroy($tmp_img);
imagedestroy($img);
return sprintf('%02X%02X%02X', $r, $g, $b);
}

Ce code est relativement rapide (bien plus que ma version C++ d'ailleurs...), on demande à redimensionner l'image à 1x1 pixel, tout en gardant l'échantillonnage des couleurs : donc calcul de la couleur moyenne dominante pour savoir quelle sera la couleur de ce seul pixel. Bien pensé et diablement plus efficace que parcourir tous les pixels à la main.

De plus, si vous avez compris le code, vous aurez requarqué que seuls les formats d'image JPEG et PNG sont pris en compte. D'autres seront à venir suivant la demande (hormis pour les images animées).


Pour les développeurs


Avant tout, sachez que ce n'est pas la mer à boire : 3.2 ko (CSS) + 3.1 ko (JS) = 6.3 ko !

Ensuite, Shaarlimages est un exemple, mais pour ceux qui veulent utiliser le même système ailleurs, voici comment faire. Dans votre code, il faut définir un conteneur avec l'ID image-container. Dans ce conteneur, chaque image doit être encadrée dans une figure. Puis incluez le code javascript en bas de page, ça devrait être bon.

Exemple :
<div id="image-container">
	<figure>
<a href="./media/00a3687b." data-original-source="https://tiger-222.fr/"><img src="./media/084d514f.image.jpg" data-original-source="https://tiger-222.fr/images/image.jpg"></a>
</figure>

<!-- Un exemple avec une image sensible (NSFW) -->
<figure data="nsfw">
<a href="./media/00a3687b." data-original-source="https://tiger-222.fr/"><img src="./media/df2ddecb.image-trop-sexy.jpg" data-original-source="https://tiger-222.fr/images/image-trop-sexy.jpg"></a>
</figure>
</div>

<script async src="https://tiger-222.fr/linear-partition.min.js"></script>
Pensez aussi à include le fichier CSS.


Améliorations possibles


Dans l'immédiat, la couleur de fond pour chaque image est calculée (couleur moyenne dominante) et une image est ajoutée par dessus pour le grain. Bien que ça ne rende pas trop mal, il faudrait revoir le mécanisme pour se rapprocher un peu plus de cette galerie (qui utilise des images).

Éventuellement, trouver un service en ligne, ou un code PHP, permettant de compresser les images (progressif pour le JPEG, et optimisations générales).

Pour le reste, libre à vous de forker, bidouiller et proposer des patches ☺