FAQ PHP
FAQ PHPConsultez toutes les FAQ
Nombre d'auteurs : 68, nombre de questions : 580, dernière mise à jour : 18 septembre 2021
- 12.1.1. Cache (5)
- 12.1.2. Plugins (8)
- 12.1.3. Admin Generator (5)
- Quelle est la meilleure version de symfony pour mon projet ?
- Installer symfony via PEAR en local
- Erreur "MySQL extension not loaded" pendant la génération du schéma
- Comment utiliser plusieurs bases de données avec Symfony et Propel ?
- Comment utiliser plusieurs bases de données avec Symfony et Doctrine ?
- Comment ajouter du JS ou du CSS entre <head> et </head> ?
- Comment insérer du code personnalisé dans la balise head (ou ailleurs) ?
- Quelle est la différence entre redirect() et forward() ?
- Comment transférer un paramètre avec forward() ?
- Mettre à jour simultanément plus d'un élément d'une page avec AJAX
- Autocomplétion de code pour Eclipse ?
- Comment faire des tests unitaires ?
- Utiliser l'URL rewriting
- Comment changer l'aspect des URL ?
Les versions 1.0, 1.1 et 1.2 sont actuellement à proscrire, il s'agit de versions de symfony dépassées, dont le support n'est plus assuré. Il reste deux versions en lice : la 1.3 et la 1.4.
La version 1.3 est prévue pour aider à la migration des projets des versions antérieures. Elle ne sera maintenue que jusqu'en novembre 2010. Elle comporte un plugin "sfCompat10Plugin" qui permet de supporter les spécificités de la version 1.0 (essentiellement les helper et le système de validation).
Télécharger et installer Symfony 1.3
La 1.4 est la version à utiliser pour les nouveaux projets. Elle sera maintenue jusqu'en novembre 2012 et ne diffère de la 1.3 que par l'absence d'une couche de compatibilité avec les versions antérieures.
Télécharger et installer Symfony 1.4
La version 2.0, encore en cours de développement, est annoncée pour début 2011. N'utiliser cette version qu'à des fins de tests ou pour des projets qui ne seront pas en ligne avant juin 2011 au mieux.
- Télécharger le fichier de channel à l'adresse : http://pear.symfony-project.com/channel.xmlTélécharger le fichier de channel PEAR pour symfony
- Dans la console, taper : pear channel-add "monChemin/channel.xml"
- Télécharger la dernière version stable du framework à cette adresse : http://www.symfony-project.org/get/symfony-stable.tgzTélécharger le framewok PHP symfony
- Dans la console, exécuter : pear install --offline "monChemin\symfony-stable.tgz"
Cela peut être utile lorsque le proxy bloque PEAR pour accéder à pear.symfony-project.com…
L'erreur "MySQL extension not loaded" durant la génération du schéma de la base de données avec Propel ?
En fait, dans ce cas symfony ne cherche pas le bon fichier de configuration php.ini.
Il faut simplement modifier le fichier php.ini situé dans le répertoire "php5" de symfony. Une alternative est de reprendre le fichier php.ini utilisé par Apache (se reporter à la fonction phpinfo() pour le localiser) mais en prenant garde d'adapter les chemins d'accès qui s'y trouvent.
Il est possible d'utiliser plusieurs base de données avec symfony et Propel. Pour ce faire, nous devons créer deux configuration dans "config/databases.yml" :
all:
propel:
class: sfPropelDatabase
param:
dsn: pgsql://base1@hostname/database1
database2:
class: sfPropelDatabase
param:
dsn: mysql://base2@hostname/database2
Lorsque c'est fait, lancez un clear-cache "symfony cc" et vous pourrez exploiter ces deux bases comme ceci :
$c
=
new Criteria();
$bd1
=
ArticlePeer::
doSelect($c
,
Propel::
getConnection('
propel
'
));
// base 1
$bd2
=
ArticlePeer::
doSelect($c
,
Propel::
getConnection('
database2
'
));
// base 2
Pour des utilisations plus avancées, vous pouvez imaginer un système de backup et "RAID".
Lien : Comment utiliser plusieurs bases de données avec Symfony et Doctrine ?
Pour utiliser plusieurs bases de données avec Symfony et Doctrine, il faut d'abord préciser que plusieurs bases de données sont à utiliser dans le fichier de configuration ad hoc. Ensuite, il suffira de définir dans le schéma quelle table sera inscrite dans quelle base de données.
Premièrement, configurons plusieurs bases de données dans le fichier idoine.
all:
doctrine_1:
class:
sfDoctrineDatabase
param:
dsn:
'
mysql:host=localhost;dbname=db
'
username:
db_user
password:
monSiBeayMotDePasseQuePersonneNeConnaît
doctrine_2:
class:
sfDoctrineDatabase
param:
dsn:
'
mysql:host=localhost;dbname=db2
'
username:
db2_user
password:
monSiBeayMotDePasseQuePersonneNeConnaîtNiNeVeutConnaître
Maintenant, dans votre schéma, il suffit d'utiliser le paramètre connection pour indiquer laquelle des deux bases de données devra héberger cette table et son contenu.
Utilisateur:
tableName:
db2.
utilisateur
connection:
doctrine_1
columns:
nomdutilisateur:
string(255
)
Lien : Comment utiliser plusieurs bases de données avec Symfony et Propel ?
On peut ajouter des lignes JavaScript simplement dans le fichier de configuration apps/application/config/view.yml où on peut trouver un paramètre javascripts. Il en va de même pour les feuilles de styles :
javascripts: [mon_script.js, mon_autre_script.js]
stylesheets: [main.css, print.css]
Il faut y insérer les noms des fichiers JavaScript et des fichiers CSS séparés par des virgules.
Vous pouvez aussi utiliser un helper dans votre fichier de template :
<?php
use_stylesheet('main.css'
);
?>
<?php
use_javascript('mon_script.js'
);
?>
Les fichiers JavaScript doivent se trouver, physiquement ou symboliquement, dans le dossier js du contrôleur, les feuilles de style dans le dossier css.
Vous pouvez aussi utiliser un fichier de configuration view.yml par module pour spécifier précisément les fichiers CSS et JS à charger pour chaque template (et, par conséquent, action). Par exemple, dans le fichier apps/APPLICATION/modules/MODULE/config/view.yml :
indexSuccess:
stylesheets: [...]
all:
stylesheets: [...]
Il suffit d'utiliser un slot. Un slot est un emplacement réservé que l'on peut placer dans n'importe quel élément : un layout, un partial ou un component. Il se comporte alors comme une variable dont on peut modifier à volonté la valeur.
Le code destiné à être placé dans le slot est contenu dans le response global, et peut être défini n'importe où.
Exemple : on souhaite intégrer des styles entre les balises <head> et </head> dans un template particulier, et uniquement dans ce template. On commence par placer le slot dans le layout.php de l'application, entre les balises <head> et </head> :
<?php
if
(has_slot('my_slot_style'
)):
?>
<?php
include_slot('my_slot_style'
) ?>
<?php
endif
;
?>
Ensuite, on définit le slot dans le template en question (ex : indexSuccess.php)
<?php
slot('my_slot_style'
) ?>
<
style type=
"
text/css
"
>
h1{
font-
size:
36
pt;
text-
decoration:
underline;
}
</
style>
<?php
end_slot() ?>
Le style voulu apparaîtra alors uniquement avec le template indexSuccess.
Notez qu'il s'agit de la méthode conseillée pour mettre un titre à vos pages. Par exemple, vous pouvez mettre ceci dans votre layout principal :
<
head>
<?php
include_http_metas() ?>
<?php
include_metas() ?>
<
title>
<?php
include_slot('title'
);
?>
</
title>
<!--
...
-->
</
head>
Vous pourrez ainsi définir très facilement un titre depuis votre template :
<?php
slot('title'
,
'Titre de la page'
)?>
Quelle est la différence entre :
$this
->
forward('
module
'
,
'
action
'
)
Et :
$this
->
redirect($url
)
La méthode forward() change simplement l'action en cours pour une autre. On reste dans la même transaction HTTP. Pour le client, on est donc toujours dans la même URL.
En revanche, la méthode redirect() redirige complètement le serveur vers la page appelée, cela produit donc une nouvelle requête HTTP complète. Ce n'est pas la même URL qui est affichée dans le navigateur.
Notez que ces deux fonctions peuvent prendre des paramètres à fournir à l'action qui est la cible du lien sous la forme d'un tableau associatif. Par exemple, si l'action cible utilise le paramètre id fourni dans l'URL, vous pourrez faire ceci :
$this
->
redirect('
monAction
'
,
array('
id
'
=>
$id
))
Si l'on souhaite accéder aux paramètres envoyés par le client, il n'est pas nécessaire de transmettre les paramètres à la nouvelle action. Par contre, si l'on a créé une variable locale dans la première action, pour la rendre disponible dans la seconde action il faut utiliser ce type de code dans la première action :
$this
->
getRequest()->
getParameterHolder()->
set('
ma_variable
'
,
$valeur
);
Dans la seconde action, on récupère la variable de cette manière :
$this
->
ma_variable =
$this
->
getRequestParameter('
ma_variable
'
);
Les helpers Javascript n'existent plus à partir de la version 1.4 de Symfony. Utilisez à la place un framework JS comme JQuery ou protoype.
Pour mettre à jour simultanément plus d'un élément dans une page, vous devez un peu bricoler la fonction remote_function qui possède une propriété très utile « complete » :
echo javascript_tag(
remote_function(array(
'
update
'
=>
'
Zone2
'
,
'
url
'
=>
'
ajax/updatediv1
'
,
'
script
'
=>
true ,
'
complete
'
=>
remote_function(array(
'
update
'
=>
'
Zone1
'
,
'
url
'
=>
"
Le nom de votre module/le nom de l'action qui va mettre à jour Zone1
"
,
'
script
'
=>
true)),
))
);
Lorsque l'appel AJAX n°1 se termine, il déclenche automatiquement l'appel n°2.
Vous pouvez même préciser le nombre d'appels que vous souhaitez en ajoutant dans chaque remote_function cette propriété « complete ».
Nous pouvons configurer notre outil Eclipse PDT ou Zend Studio for Eclipse pour nous faciliter le travail :
- Rendez-vous sur PHP Explorer et faites dérouler votre projet ;
- Cliquez doit sur Include Paths et sélectionnez Configure Include Path ;
- Sélectionnez l'onglet librairies et cliquez sur add External Folder pour ajouter le répertoire de votre projet Symfony à la racine.
Pour ajouter également l'autocomplétion pour Propel, éditez la ligne où se trouve propel.builder.addComments :
propel.builder.addComments = true
Les tests unitaires sont intégrés dans symfony et c'est une bonne choses pour connaître l'impact de nos mises à jour sur nos modules.
-
diag($msg
) // Affiche un commentaire sans faire de test
-
ok($test
,
$msg
) // Teste une condition et ne retourne aucunes erreurs si elle est vraie
-
is($value1
,
$value2
,
$msg
) // Compare deux valeurs et ne retourne aucunes erreurs si elle est vrai
-
isnt($value1
,
$value2
,
$msg
) // Test l'inégalité de deux valeurs
-
like($string
,
$regexp
,
$msg
) // Test une chaine de caractère à travers un expression régulière
-
unlike($string
,
$regexp
,
$msg
) // Contraire de like
-
cmp_ok($value1
,
$operator
,
$value2
,
$msg
) // Compare deux arguments avec un opérateur
-
isa_ok($variable
,
$type
,
$msg
) // Vérifie le type d'un argument
-
isa_ok($object
,
$class
,
$msg
) // Vérifie la Classe d'un objet
-
can_ok($object
,
$method
,
$msg
) // Vérifie une méthode d'une classe ou d'un objet
-
is_deeply($array1
,
$array2
,
$msg
) // Vérifie que deux tableaux on les mêmes valeurs
-
include_ok($file
,
$msg
) // Vérifie si un fichier existe et qu'il a bien pu être inclut
-
fail
() // Une faille : Utile pour tester des excpetions
-
pass
() // Valider : Pour tester une exception
-
skip($msg
,
$nb_tests
) // Nombre de test à échapper : pour les tests conditionnels
-
todo() // Message compté comme un test
> php symfony test-unit maFonction ## Test maFonctionTest.php
> php symfony test-unit maFonction maSecondeFonction ## Execute deux test : maFonctionTest.php et maSecondeFonctionTest.php
> php symfony test-unit '*' ## Execute tout les test du répertoire test/unit
Lorsque vous créez une application, un fichier situé dans apps/<monapplication>/config se nommant settings.yml, contient les configurations principales de symfony.
Pour chaque environnement, vous pouvez spécifier une directive :
.settings:
no_script_name: off (ou "on" pour l'utilisation du url rewriting)
Lors de votre link_to, si le no_script_name est à off, alors index.php sera présent dans votre URL (utilisation de l'INFOPATH seul). Dans le cas contraire, vous ne le verrez plus.
Lorsque vous créez des articles ou des billets pour votre blog, vous voudriez changer l'aspect de vos URL pour qu'elles soient le plus facilement référencées.
Nous allons donc pour cela configurer la classe de notre modèle concernée. Nous prendrons Articles.php que Propel à généré à partir du schema.yml "_attributes: { phpName: Articles }". Commencez par éditer le fichier lib/model/Articles.php :
class Articles extends
BaseArticles
{
public
function
getUrlTitle()
{
// Suppression et conversions des caractères
$result
=
self
::
remove_accents($this
->
getTitle());
$result
=
strtolower($result
);
$result
=
preg_replace('/\W/'
,
' '
,
$result
);
$result
=
preg_replace('/\ +/'
,
'-'
,
$result
);
$result
=
preg_replace('/\-$/'
,
''
,
$result
);
$result
=
preg_replace('/^\-/'
,
''
,
$result
);
return
$result
;
}
public
function
remove_accents($str
,
$charset
=
'utf-8'
)
{
$str
=
htmlentities($str
,
ENT_NOQUOTES,
$charset
);
$str
=
preg_replace('#\&([A-za-z])(?:acute|cedil|circ|grave|ring|tilde|uml)\;#'
,
'\1'
,
$str
);
$str
=
preg_replace('#\&([A-za-z]{2})(?:lig)\;#'
,
'\1'
,
$str
);
// pour les ligatures e.g. 'œ'
$str
=
preg_replace('#\&[^;]+\;#'
,
''
,
$str
);
// supprime les autres caractères
return
$str
;
}
}
Maintenant, créons qui se chargera de récupérer l'id de l'article pour pouvoir l'afficher :
public function executePermalink()
{
/* Methode de lien permanent (Doc. Symfony) */
$posts
=
PostPeer::
doSelect(new Criteria());
$title
=
$this
->
getRequestParameter('
title
'
);
foreach ($articles
as $articles
)
{
if ($post
->
getStrippedTitle() ==
$title
)
{
$this
->
getRequest()->
setParameter('
id
'
,
$article
->
getId());
return $this
->
forward('
articles
'
,
'
show
'
);
}
}
$this
->
forward404();
}
Dans la page qui liste les articles, changer l'URL par :
link_to($article
->
getTitle(),
'
@article?title=
'
.
$article
->
getStrippedTitle())
Pour finir, nous allons annoncer dans le fichier routing.yml, que nous voulons utiliser l'action permalink lorsque nous voudrons afficher un article apps/monapplication/config/routing.yml :
article:
url: /articles/:title
param: { module: articles, action: permalink }