#18777

GitHub - moonmoon/moonmoon: moonmoon is a simple feed aggregator (planet like)

Un petit aggrégateur RSS.

Mouais, ça peut servir si on a 4 ou 5 flux. Je viens de tester avec mes ~180 flux et c’est leeeeeent.
En local (quadricore dédié avec 20 Go de Ram) la page met 48 secondes à charger.

Ça semble mettre à jour les flux à chaque chargement de la page (bien qu’il semble utiliser un cache du fichier RSS). Si c’est pour avoir des perfs de merde, je vois pas l’intérêt de faire du « sans BDD ».

Au début, quand je codais, je me faisais plaisir en codant des trucs sans SGBD (juste du XML), ou sans JS, simplement histoire de prouver (je ne sais pas à qui) que c’était possible.
Et après on découvre que c’est quand-même nettement plus rapide/pratique/fonctionnel quand on utilise des outils fait exprès pour ce qu’on veut faire.

Ce n’est pas mal de réinventer la roue (au contraire), mais parfois il faut quand même reconnaître qu’il existe des outils mieux que ce qu’on pourra jamais faire soi-même.

On peut faire un aggrégateur RSS juste en HTML/CSS (mettez des iframe et du XSLT et on peut faire un truc, je pense), et ça serait une jolie prouesse, mais inutilisable en soi.

https://github.com/moonmoon/moonmoon

#18207

Note

Dans PHP, si vous avez un tableau associatif dont les clés sont numériques, certaines fonctions comme array_reverse() font réindexer le tableau une fois le reverse() effectué.

Si les clés sont une chaîne, elles sont conservées (le tableau est simplement inversé).

Donc si vous avez ça :

array(4 => "quatre", 8 => "huit");

Vous obtiendrez ça :

array(0 => "huit", 1 => "quatre");

Et non pas :

array(8 => "huit", 4 => "quatre");

Je me suis fait avoir : je voulais une clé unique pour un tableau. Pour ça, j’utilise parfois crc32(), une fonction de hashage relativement rapide.

Sauf que en PHP, crc32() retourne un entier. Mes index ont donc disparus après le reverse().
J’ai dû me rabattre sur md5() pour le hash unique.

J’aurais aussi pu prendre hash('crc32', $i), qui lui retourne une chaîne en hexa.

Fin bref, soyez vigilants.

https://lehollandaisvolant.net/?mode=links&id=20190122172625

#18041

[PHP] Note : virer tous les accents d’une chaîne unicode (latin)

Pour enlever les accents, tildes, trémas, cédilles de toutes les lettres diacritiques latines, en PHP :


$texte = htmlentities($texte, ENT_QUOTES, 'UTF-8');
$texte = preg_replace('#&([a-z]{1,2})(acute|grave|circ|uml|cedil|tilde|ring|slash|caron|lig);#', '$1', $texte);

On commence par transformer les lettres accentuées en entités HTML : « é » devient « &eacute ».
Ensuite, on remplace cette chaîne la par la première lettre après le « & ».

Ces entités sont toutes formées de la même façon :
à => à
è => è
ò => ò

ä => ä
ö => ö
ü => ü

Pour les ligatures, c’est pareil :
œ => œ
æ => æ
ß => $szlig;

Par contre ça ne fait que les minusucles, les majuscules ne marchent pas comme ça.

https://lehollandaisvolant.net/?mode=links&id=20181208140630

#17662

Note : PHP, curl_multi et barre de progression

Ok… donc en PHP dans mon lecteur RSS qui doit récupérer en parallèle 170 URL, j’affiche un petit compteur.

Le truc, c’est que c’est forcément dans une boucle while, et que cette boucle se fait aussi rapidement que le CPU le peu.

Donc si PHP envoie au navigateur un « +1 » à chaque fois qu’un flux est récupéré, il l’envoie quelques millions de fois par seconde : impensable, donc, ce qui fera des dizaines de Mo de données juste pour ça.

Du coup, j’avais mis un usleep(100000) dans la boucle… ça marchait. Par contre, ça bloquait également la récupération des flux ! Certains flux posaient donc problème…

Du coup j’ai remplacé ça par un test sur microtime(). Par contre, je maintiens un tout petit usleep() : la différence est flagrante : le sleep est assez faible pour pas que cURL coupe la requête, mais assez long pour éviter que le CPU ne fasse 1 milliard de tests par seconde :


	$running = 0;
	$utime = microtime(true);

	do {
		curl_multi_exec($master, $running);
		usleep(500);

		// echoes the nb of feeds remaining
		if ($utime + 1 < microtime(true)) {
			echo ($total_feed-$running).'/'.$total_feed.' '; ob_flush(); flush();
			$utime = microtime(true);
		}
	} while ($running > 0);

https://lehollandaisvolant.net/?mode=links&id=20180807154339

#16855

Date.prototype.getTimezoneOffset() - JavaScript | MDN

gnîîîîî !

Encore ces incohérences entre JS et PHP.
Ici sur la sortie d’une date en une chaîne au format ISO 8601 : en PHP, la chaîne prend en compte le décalage par rapport à l’UTC. En JS, il n’y a pas de décalage : tout est en UTC.

Quant à calculer ce décalage : un UTC+2 (correspondant à Paris en été, par exemple), il est positif pour PHP (logique) mais négatif en JS (probablement car UTC est 120 minutes de moins que l’heure locale).

https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date/getTimezoneOffset

#16800

Date.prototype.getMonth() - JavaScript | MDN

Donc…
En JS, les mois vont de 0 à 11.
En PHP, les mois vont de 1 à 12.

Et les jours ?
En JS, les jours vont de 1 à 31.
En PHP, les jours vont de 1 à 31.

Le JS c’est à se taper la tête contre les murs, vraiment. Et là c’est juste une broutille (suffit de faire un −1 entre les deux langages [oui car mon PHP écrit du JS]). Mais parfois c’est bien plus chiant à corriger…

https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date/getMonth

#15790

PHP: Possible modifiers in regex patterns - Manual

Donc pour faire en sorte que les caractéristiques accentués soient pris en compte dans \w, il faut ajouter le flag "u" (en minuscule).

Retourne false :

preg_match('#\w#', 'é') 

Retourne true :

preg_match('#\w#u', 'é') 
http://php.net/manual/en/reference.pcre.pattern.modifiers.php

#15487

Note : PHP, file_get_contents et URL

Sur certains serveurs, file_get_contents(), copy() et quelques autres fonctions qui peuvent fonctionner avec des URL (chemins distants) ne marchent pas : la directive INI allow_url_fopen est mise à Off.

Pour palier à ça, on peut utiliser cURL pour récupérer le fichier. Sur les serveurs qui n’ont que cette directive mise à Off, cURL (s’il est installé) fonctionnera.

On utilisera alors ça :

// request
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
$file_content = curl_exec($curl_handle);
curl_close($curl_handle);
// saving
file_put_contents($file_name, $file_content);


Dans les cas où le serveur bloque toutes les connexions sortantes, il n’y a pas de solutions pour faire des requêtes externes.
http://lehollandaisvolant.net/?mode=links&id=20160528185414

#15466

PNG Optimization with GD library

Quand on produit des PNG avec PHP/GD, les images sont rarement optimisées. Cette page donne quelques pistes.

Moi par exemple, je tente de reproduire ça en plus léger.
En somme, c’est une simple matrice 5x5 avec deux couleurs dans la palette.

Il me suffit d’ajouter ça, juste avant le imagepng() :
imagetruecolortopalette($image_ressource, false, 256);


La taille d’une icône 512x512 passe ainsi de 2 131 octets à 283 octets (~85% de réduction).

L’image passée dans optipng me revient à la même taille. Pour les icônes avec très peu de couleurs c’est donc idéal. Pour les autres png, voyez l’article.
http://perplexed.co.uk/1814_png_optimization_with_gd_library.htm

#15429

Note : PHP, imagerotate

Ok, donc "imagerotate" en PHP me donne un segfault si l’angle==360°.

[Sun May 22 20:01:30.476001 2016] [core:notice] [pid 1747] AH00052: child pid 14628 exit signal Segmentation fault (11)


Tout va bien

Visiblement je ne suis pas le seul : https://github.com/banister/devil/issues/13
Et j’ai aussi vu d’autres erreurs, dans d’autres langages (datant de 2010). La source serait dans les Lib en C utilisées.
http://lehollandaisvolant.net/?mode=links&id=20160522200404

#14936

GitHub - timovn/local-favicon-cache: Creates a local favicon cache using Google-Favicon grabber

Google possède un service (non documenté) pour trouver les favicons des sites : http://www.google.com/s2/favicons?domain=google.com

Mon script (PHP) constitue un cache local des favicons en utilisant le service de Google.
Je compte l’utiliser pour le lecteur RSS de Blogo.

Le truc bien c’est que c’est le serveur qui fait la requête vers Google, sans referer ni rien. Ce n’est pas l’utilisateur, donc c’est bien pour la vie privée.
Une fois qu’une requête chez Google est faite et que la favicon est en local, c’est l’icône locale qui est servie sans requête Google.

Il fonctionne en se basant sur le script de Mitsu pour Gravatar, c’est le même principe et pratiquement le même code : https://suumitsu.eu/wiki/doku.php?id=php:cache_gravatar
https://github.com/timovn/local-favicon-cache

#14918

Note : rappel PHP

NEVER TRUST USER INPUT

C’est valable pour les formulaires POST et GET mais aussi plein d’autres choses :
– cookies
– variables de sessions
– noms de fichiers uploadés ($_FILES)
– les types de fichiers (dont MIME)
– variables dans le php.ini
– …

Sans oublier des vérifications spéciales dans certains cas : si la chaîne « . » (un simple point) est grammaticalement valable pour un pseudo ou un mot de passe, ça devient très dangereux quand il s’agit d’un nom de fichier (« . » c’est un raccourcis pour dire « dossier courant », comme « .. » signifie « dossier parent »).

Si en PHP vous avez un script pour renommer un fichier, un nouveau nom « . » sera valide pour le htmlspecialchars(). Mais au moment où le serveur transmet la requête « renomme le fichier abc.jpg en "." » au système d’exploitation ou au système de fichier, dans le meilleur des cas ça génère une erreur, dans le pire ça écrase le dossier courant et son contenu (le "." c’est le dossier courant et là on renomme un fichier par dessus).

Et pour supprimer un fichier, pareil : http://lehollandaisvolant.net/tuto/php/#supprimer-un-fichier


Enfin, l’utilisateur est toujours très con quand il s’agit d’utiliser un logiciel. Il fera toujours n’importe quoi, et encore plus si ça permet de faire planter l’ordinateur.
C’est très fatiguant de devoir penser à tout, comme ici avec la gestion du CSV http://sebsauvage.net/wiki/doku.php?id=csv . Heureusement, ici certains l’ont fait.

Si ce n’est pas le cas dans ce que vous faites, je conseille de ne pas avoir peur de faire une application limitée mais qui fonctionne plutôt qu’un truc illimité qui plante, même dans seulement 0,01% des cas : la loi de Murphy ne plante pas elle.

Par exemple, pour gérer les extensions de fichiers, je préfère dresser une liste avec les 20 extensions les plus communes (png, doc, jpg, mp3, apk…) et mettre tout le reste dans « autres », plutôt que d’essayer de détecter l’extension des fichiers (par régex ou autres).

Tôt ou tard, il y aura un urluberlu avec un nom de fichier de 500 caractères, ou avec une extension de 500 caractères, ou sans extensions, ou une extension en unicode, ou une extension en unicode-privé sur une fonte que vous n’avez pas, ou avec des caractères d’échappement.

Afficher 500 caractères ce n’est pas un soucis en soit, mais ça déforme l’affichage si l’absence d’espaces génère un non-retour à la ligne…

Ah et, si votre fichier est envoyé depuis GNU/Linux, il peut contenir des espaces et des caractères unicodes ou de la ponctuation. Windows n’aime pas ça et parfois il refusera d’enregistrer ce fichier au nom bizarre (ça dépend du système de fichier : FAT32 gère ça très mal en tout cas).

Bref, faut avoir une vision d’ensemble des chose : uploader un fichier, c’est pas juste une requête "files", c’est aussi penser à celui qui maintient caps-lock allumé quand il renomme ses photos avec des noms à rallonge sous Windows sur un clavier russe.
http://lehollandaisvolant.net/?mode=links&id=20160331195130