Kamelot Blog

Aller au contenu | Aller au menu | Aller à la recherche

jeudi 11 octobre 2012

jeu
11
oct '12

Petite astuce de développement avec SphinxSearch

--dump-rows <FILE> dumps rows fetched by SQL source(s) into the specified file, in a MySQL compatible syntax. Resulting dumps are the exact representation of data as received by indexer and help to repeat indexing-time issues.

Si vous ajoutez l'option --dump-rows lors de votre indexation, un fichier sera généré avec un dump sql.

Moi ce qui m'intéresse ici c'est l'entête du fichier

# field 0: ressource_title
# field 1: ressource_subtitle
# field 2: ressource_description
# field 3: ressource_category_name
# field 4: ressource_category_description
# sql_attr_timestamp = created # attr 0
# sql_attr_timestamp = online_from # attr 1
# sql_attr_timestamp = online_until # attr 2
# sql_attr_uint = display_counter # attr 3
# sql_attr_uint = vote_counter # attr 4
# sql_attr_uint = parent_id # attr 5
# sql_attr_timestamp = indexing_date # attr 6

Je copie ca dans mon code php ca fait un memento parfait.

Alleï tant qu'à faire une astuce de plus

regardez l'attribut n°6

dans mon sql d'indexation j'ai toujours en dernier lieu

         now() AS indexing_date                                              \

Ca me permet de donner la date de lecture de l'information. L'index pouvant être vu comme un cache. Cette information est parfois importante ou tout du moins utile

mercredi 25 janvier 2012

mer
25
jan '12

5 petites choses qui ne prennent pas beaucoup de temps pour s'investir dans la communauté php

original : http://devzone.zend.com/article/12450-Get-involed-in-the-PHP-community-5-easy-steps-that-take-less-than-5-minutes-each

1 ° Mettez en place un tag "PHP" sur votre Blog

Si vous parlez de php sur votre blog mais aussi d'autres choses.

  • Proposez un tag ou une catégorie dédiée à PHP
  • Proposez un feed rss de ce tag ou catégorie
  • Soyez actif dans cette catégorie
  • Portez cette catégorie à la connaissance des "planets"
    • http://www.planete-php.fr/
    • http://www.planet-php.net/blog/

lundi 16 mai 2011

lun
16
mai '11

Le saviez vous ? PHP_EOL & REQUEST_TIME

Pour ne pas devoir utiliser "\n"

J'avais pour habitude de faire

defined('NL') || define('NL',"\n");

et j'avais du code du style

echo 'foo' . NL
.      'bar';

En fait depuis PHP 4.3.10 et PHP 5.0.2, la constante PHP_EOL existe nativement pour cela.

echo 'foo' . PHP_EOL
.      'bar';

Et l'intérêt principal, est dans les commentaires.

La valeur de PHP_EOL dépends de l'OS. On peut avoir \n, \r\n ou \r comme valeurs.

Ca vaut le coup de relire la liste des constantes préétablies. Ca peut donner des idées.

Dans le même ordre d'idée, un timestamp représentant le début de la demande est disponible dans la variable $_SERVER['REQUEST_TIME'] depuis PHP 5.1.

dimanche 24 octobre 2010

dim
24
oct '10

Tortoise checkout partiel puis complet

Nondidjos, je viens de trouver un truc que je cherchais depuis des plombes.

Quand on fait un checkout avec Tortoise, on peut choisir

  • Full Recursive
  • Immediate children, including folders
  • Only File Children
  • Only this item

Si on choisi autre chose que Full Recursive

Ben on a pas tout :)

Et ça m'arrive souvent d'en avoir besoin, par exemple quand certains sous-répertoires ne m'intéressent pas et sont "bien remplis" ...

Problème d'autres m'intéressent, comment les checkouter eux ?
J'ai enfin trouvé la solution.

Dans l'opération Update révision on retrouve cette option.

Il faut prendre Head Revision

Et en dessous on a le sous menu Checkout Depth

Et la miracle, ça marche le checkout se prolonge

On se retrouve avec le contenu du sous répertoire

On peut même sélectionner plusieurs sous répertoires (vive le ctrl-click) d'un coup

mardi 3 août 2010

mar
03
aoû '10

Récupération des données d'un formulaire

Voici un petit formulaire:

[php]
<form>
  <input type="radio" name="BT.123" value="actif" />
  <input type="radio" name="BT.123" value="inactif" />
  <input type="submit" value="Submit" />
</form>

<?php
  echo "GET: ", $_GET['BT.123'];
  echo "POST: ", $_POST['BT.123'];
  echo "REQUEST: ", $_REQUEST['BT.123'];
?>

Qu'est ce qui s'affichera si on choisi "inactif" et qu'on soumet le formulaire ?


réponse dans le 1er commentaire

samedi 24 juillet 2010

sam
24
juil '10

Batch : Attention à la mémoire vive et au reste ...

Olivier Hoareau nous rappelle de faire attention à la mémoire vive dans les batch.

Je viens juste en remettre un couche par rapport à des petits bugs identifiés récemment dans différentes relecture de vieux code.

boucle environementée

Il ne faut pas voir un batch comme une application, mais comme un environnement à reseter à chaque itérations.

C'est à dire que la consommation de vos ressources doivent être le même en fin de chaque loop. Et il ne faut qu'un loop.

Classiquement on a lecture - traitement - écriture.

Il faut éviter le réflexe de "tout lire" -> boucler sur ce qu'on a lu -> "tout écrire"

Il faut envisager le processus "lecture - traitement - écriture." au niveau de la ligne.

Un exemple, avec un fichier CSV à transformer en tableau HTML.

Premier réflexe, on découpe traitement et affichage.

<?php
 $arrayContenuDuCsv = readCsvFile(); 
 // contient une boucle qui "lit" toutes les lignes
 
$arrayResultat = traitementDesDonnees($arrayContenuDuCsv);
 // contient une boucle effectue les traitements sur chaque ligne
 
 $stringHtml = arrayToHtmlTable($arrayResultat); 
 // contient une boucle effectue les traitements sur chaque ligne
 
 // traitement fini, j'affiche
 echo $stringHtml;

le problème c'est que

<?php
 $arrayContenuDuCsv = readCsvFile(); 
 // contient une boucle qui "lit" toutes les lignes
 
 // ici $arrayContenuDuCsv est de taille non maitrisée, dépendant de la taille du fichier
 
 $arrayResultat = traitementDesDonnees($arrayContenuDuCsv);
 // contient une boucle effectue les traitements sur chaque ligne
 
 // ici $arrayResultat est de taille non maitrisée, dépendant de la taille du fichier
 // pire, comme on a pas encore fait de "unset" de $arrayContenuDuCsv on a le csv en double en mémoire!!!!
 
 $stringHtml = arrayToHtmlTable($arrayResultat); 
 // contient une boucle qui éffectue les traitements sur chaque ligne
 
 
 //ici $stringHtml est de taille non maitrisée, dépendant de la taille du fichier
 // pire, comme on a pas encore fait de "unset" de $arrayResultat on a le csv en double, 
 // et si on a à faire a un très mauvais codeur, il n'a même pas fait de unset($arrayContenuDuCsv)
 // et on a le fichier en triple
 
 // traitement fini, j'affiche
 echo $stringHtml;

Il faut donc voir l'application au niveau du traitement de la ligne

<?php
 $arrayContenuCsv = readCsvRow(); // <- contient une boucle qui "lit" UNE ligne
 
 //ici $arrayContenuCsv est de taille maitrisée, 1 ligne
 
 $arrayResultatLigne = traitementDesDonnees($arrayContenuCsv);
 // contient un traitement identique pour chaque ligne
 
 //ici $arrayResultat est de taille maitrisée, 1 ligne
 
 $stringHtml = arrayToHtmlRowTable($arrayResultat);  //ici $stringHtml est de taille maitrisée, 1 ligne
 // traitement fini de ligne, j'affiche
 echo $stringHtml;

Bien entendu il faut mettre tout ceci dans une boucle, ajouter le header et le footer de ma table, mais ca reste du traitement unique.

Initialiser ses variables.

Voici un autre cas de mauvaise écriture que j'ai rencontré.

[php]
<?php
$arrayData = array();
$arrListedeListes = getListeDeListe();
foreach ($arrListedeListes as $arrListe )
{
     foreach ($arrListe as $ligne)
     {
           $arrayData[]=getResultatDuTraitementDeLaLigne($ligne);
     }
     $result= ecritureDesDatas($arrayData);
}

Le développeur a vu qu'en faisant cela au deuxième passage le traitement des données incluait le nouvelles mais aussi celle de la passe d'avant.

Solution appliquée par le développeur

[php]
<?php
$arrayData = array();
$arrListedeListes = getListeDeListe();
foreach ($arrListedeListes as $arrListe )
{
     $i=0; // <- il a réinitialisé son compteur
     foreach ($arrListe as $ligne)
     {
           $arrayData[$i]=getResultatDuTraitementDeLaLigne($ligne);
           $i++;
     }
     $result= ecritureDesDatas($arrayData);
}

Très mauvaise idée parce qu'en fait ce n'est qu'une version aussi erronée que la précédente mais en masquant un peu le problème.

En effet, en écrasant sans effacer la liste précédente, il se fait que dés qu'une liste était plus courte que la précédente, les lignes en surplus était reconsidérées à nouveau.

[php]
<?php
$arrListedeListes = getListeDeListe();
foreach ($arrListedeListes as $arrListe )
{
     $arrayData = array();

     foreach ($arrListe as $ligne)
     {
           $arrayData[$i]=getResultatDuTraitementDeLaLigne($ligne);
           
     }
     $result= ecritureDesDatas($arrayData);
}

Autres outils

Avec Zend_Framework il existe un outil qui permet de gérer le traitement gourmands en entrée et surtout en sortie c'est Zend_Memory.

Il va permettre de gérer des grosses entités de données en plaçant hors de la mémoire vive ce qu'on n'utilise pas.

Il place l'inutilisé dans un des backends Zend_Cache.

Pensez aussi à lire l'article d'Olivier Hoareau : attention à la mémoire vive.

samedi 26 juillet 2008

sam
26
juil '08

badges facebook

Maintenant on peut créer des badges sur facebook

jeudi 24 janvier 2008

jeu
24
jan '08

SELECT WEEK( 1er Janvier);

SELECT WEEK('2008-01-01'); // 0;
SELECT WEEK('2008-01-07'); // 1;
SELECT WEEK('2008-02-03'); // 4;
SELECT WEEK('2008-12-31'); // 52;

WEEK ne compte que les semaines complètes.

Certains vont dire, mais non la première semaine c'est la 0.

Non, non, en voici la preuve

SELECT DAYOFWEEK('2008-01-01'), # 3
       DAYOFWEEK('2007-01-01'), # 2
       DAYOFWEEK('2006-01-01'), # 1 <- ICI l'année commence le premier jour de la semaine
       DAYOFWEEK('2005-01-01'), # 7
       DAYOFWEEK('2004-01-01'), # 6
       DAYOFWEEK('2003-01-01'), # 5
       DAYOFWEEK('2002-01-01'); # 4 

Du coup

SELECT WEEK('2008-01-01'), # 0
       WEEK('2007-01-01'), # 0
       WEEK('2006-01-01'), # 1 <-on est bien la première semaine complète de l'année
       WEEK('2005-01-01'), # 0
       WEEK('2004-01-01'), # 0
       WEEK('2003-01-01'); # 0 

et du coup

SELECT WEEK('2008-12-31'), # 52
       WEEK('2007-12-31'), # 52
       WEEK('2006-12-31'), # 53
       WEEK('2005-12-31'), # 52
       WEEK('2004-12-31'), # 52
       WEEK('2003-12-31'); # 52 

En fait maintenant il y a une deuxième paramètre.

WEEK(date ,mode)

Voici ce que dit le manuel.

Avec deux arguments, la fonction WEEK() vous permet de spécifier si les semaines commencent le Dimanche ou le Lundi et la valeur retournée sera dans l'intervalle 0-53 ou bien 1-52. Lorsque l'argument mode est omis, la valeur de la variable default_week_format (ou 0 en MySQL 4.0 ou plus ancien) est utilisée.

Voici un tableau explicatif sur le fonctionnement du second argument : Valeur Signification

  • 0 : La semaine commence le Dimanche;l'intervalle de valeur de retour va de 0 à !2; la semaine 1 est la première semaine de l'année
  • 1 : La semaine commence le Lundi;l'intervalle de valeur de retour va de 0 à !2; la semaine 1 est la première semaine de l'année qui a plus de trois jours
  • 2 : La semaine commence le Dimanche;l'intervalle de valeur de retour va de 1 à !2; la semaine 1 est la première semaine de l'année
  • 3 : La semaine commence le Lundi;l'intervalle de valeur de retour va de 1 à !2; la semaine 1 est la première semaine de l'année qui a plus de trois jours
  • 4 : La semaine commence le Dimanche;l'intervalle de valeur de retour va de 0 à !2; la semaine 1 est la première semaine de l'année qui a plus de trois jours
  • 5 : La semaine commence le Lundi;l'intervalle de valeur de retour va de 0 à !2; la semaine 1 est la première semaine de l'année
  • 6 : La semaine commence le Dimanche;l'intervalle de valeur de retour va de 1 à !2; la semaine 1 est la première semaine de l'année qui a plus de trois jours
  • 7 : La semaine commence le Lundi;l'intervalle de valeur de retour va de 1 à !2; la semaine 1 est la première semaine de l'année

Le mode 3 est disponible depuis MySQL 4.0.5. Le mode 4 est disponible depuis MySQL 4.0.17.

mercredi 16 janvier 2008

mer
16
jan '08

REPLACE reset les valeurs non spécifiées

# Je crée une table
DROP TABLE IF EXISTS `testReplace`;
CREATE TABLE `testReplace` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `a` INT(11) DEFAULT '1',
  `b` INT(11) DEFAULT '2',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
#J'y ajoute 2 records /lignes/tuples
INSERT INTO `testReplace` 
	(`a`, `b`)
	VALUES
	(1, 1),(2,2);
SELECT * FROM  `testReplace`;
 id | a | b
============
  1 | 1 | 1
  2 | 2 | 2
#Je remplace la première valeur de la première ligne 
REPLACE INTO `testReplace` 
	SET `id`=1, a=3;
# que vaut b ? 
  SELECT * FROM  `testReplace`;
 id | a | b
============
  1 | 3 | 2
  2 | 2 | 2

B a repris sa valeur par défaut

En pratique cela veut dire que si on fait un replace et qu'on ne précise pas toutes les colonnes les colonnes non-spécifiées prennent la valeur par défaut alors qu'on peut s'attendre à un "non" changement.

Il est donc faux de croire que REPLACE c'est un exist(id) ? UPDATE : INSERT

C'est plutôt

  • exist(id) ? DELETE
  • suivi d'un INSERT

Il faut donc utiliser une autre méthode.

INSERT INTO table (id,a) VALUES (1,3)
  ON DUPLICATE KEY UPDATE a=3;

mardi 26 juin 2007

mar
26
juin '07

SimpleXml et attribut(s) avec tiret(s) dans le nom

imaginez un fichier

<?xml version='1.0' standalone='yes'?>
<semaines>
  <semaine>
    <travail>
      au boulot
    </travail>
    <week-end>
      at home
    </week-end>
  </semaine>
</semaines>

si on veut le lire avec simpleXML

[php]
$xmlstr = file_get_contents('lefichier.xml');
$xml = new SimpleXMLElement($xmlstr);

echo $xml->semaine[0]->week-end;


// Il ne va pas être content avec le -

// Il faut écrire cela comme ceci


echo $xml->semaine[0]->{'week-end'};

mercredi 23 mai 2007

mer
23
mai '07

SELECT WEEK( 1er Janvier);

WEEK ne compte que les semaines complètes.

SELECT WEEK('2007-01-01'); // 0;
SELECT WEEK('2007-01-07'); // 1;
SELECT WEEK('2007-05-23'); // 20;

jeudi 3 mai 2007

jeu
03
mai '07

Un peu plus sur Flickr

Ce dimanche, Damien et Geoffrey parlaient dans pureBlog de flickr, et picasaweb.

J'utilise flickr depuis un an, et j'ai peu utilisé les autres mais voici quelques astuces pour les utilisateurs.

Lire la suite...

mercredi 28 mars 2007

mer
28
mar '07

Zend : impossible de se connecter

Un truc tout con avec zend Studio.

Quand je démarre Studio dans le train il m'enquiquinait tout le temps avec un "impossible de se connecter à ..."

Je pensais que c'était le debugueur. Il n'en est rien. En fait je travaille tout le temps en "projets" et donc pas souvent en mode "système de fichier" dans le gestionnaire. Là même où on peut ajouter des connections FTP. Hors par défaut ces connections se crée avec "se reconnecter au démarrage" Ce que Zend n'arrive pas à faire quand je suis hors connection.

Me voilà enfin tranquille avec ca.

A coté de cela, les premières expériences d'utilisation du sois-disant client SVN intégré ne sont pas emballantes.

Ce n'est qu'un envoi de commande à un client externe (fourni). J'ai déjà rencontré plusieurs problèmes, mes collègues aussi.

Va falloir rassembler ca et feedbacker Zend.

vendredi 2 février 2007

ven
02
fév '07

x= a ? b :c et a ? x : y = b;

Voici un post pas très utile au premier plan, mais qui a pour but de montrer que parfois il y a des trucs tordus faisable en php.

Lire la suite...

lundi 20 novembre 2006

lun
20
nov '06

iMacros for Firefox

iMacros for Firefox by iOpus Inc. pour Firefox 1.5 - 2.0.0.*

Voilà une petite extention qui devrait pouvoir aider en phase de test. On peut automatiser son firefox en enregistrant et rejouant une suite de manoeuvres

Il y a plus d'informations ici

... à découvrir

dimanche 27 août 2006

dim
27
aoû '06

CDT - Central Daylight Time

La première ligne du log de reconstruction de la doc de PEAR est la suivante :

>>> starting build at: Sun Aug 20 13:20:47 CDT 2006

Je me demandais quel TIMEZONE était représenté par CDT.

Lire la suite...

vendredi 25 août 2006

ven
25
aoû '06

La commande UNION

Une autre devinette de little Noyes

Voici 2 définitions de tables:

CREATE TABLE `users1` (
`name` varchar(10) default NULL,
`birthday` date default NULL
);

CREATE TABLE `users2` (
`name` varchar(10) default NULL,
`birthday` date default NULL
);
After inserting some data, we get the following row counts:

SELECT COUNT(*) FROM users1;
+----------+
| COUNT(*) |
+----------+
| 15       |
+----------+

SELECT COUNT(*) FROM users2;
+----------+
| COUNT(*) |
+----------+
| 12       |
+----------+
Maintenant voici une requête:

SELECT * FROM users1 
UNION 
SELECT * FROM users2;

Combien de rang y aura-t-il dans le résultat ?
  • exactement 27
  • au minimum 12
  • au minimum 15
  • entre 1 et 27
  • Zero ou plus

Voir la réponse ▼

ven
25
aoû '06

Enigme en mysql

Trouvée sur le A Little Noise
SELECT * FROM theTable;
+----+----------+
| id | data     |
+----+----------+
|  1 | milieu   |
|  2 | premier  |
|  3 | showLast |
+----+----------+

Maintenant trions sur `data`.

SELECT * FROM theTable ORDER BY data;
+----+----------+
| id | data     |
+----+----------+
|  3 | showLast |
|  1 | milieu   |
|  2 | premier  |
+----+----------+

hum??? Peut-être sur le serveur n'a pas compris.

SELECT * FROM theTable ORDER BY data ASC;
+----+----------+
| id | data     |
+----+----------+
|  3 | showLast |
|  1 | milieu   |
|  2 | premier  |
+----+----------+

Que se passe-t-il ? Il assure ne pas avoir switché vers une quelquonque collation inversée.

Voir la réponse ▼

lundi 21 août 2006

lun
21
aoû '06

Concatener malgré des null

SELECT CONCAT('a','foo',null,'bar');

donne NULL parce que c'est son comportement normal.

Si toutefois on désire avoir un retour avec les NULL considérés comme chaînes vides une autre fonction viendra à notre secours.

Lire la suite...

jeudi 27 avril 2006

jeu
27
avr '06

PHP GOTCHAS!

Traduction de l'article http://devzone.zend.com/node/view/id/168
écrit par John Herren le Vendredi, Avril 21, 2006


Appelez-les obscures, appelez-les injustifiées, appelez-les des "erreurs de newbies."
Quelque soit le nom, vous les avez plus que probablement déclenchées vers le début dans votre apprentissage de codage en PHP par des comportements apparemment impairs ou illogiques du langage.
PHP étant un langage faiblement typé, des choses bizarres qui en découlent peuvent se produire. PHP est un langage facile à reprendre pour le codeur occasionnel

Lire la suite...

Tags