<?xml 
version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="https://www.spip.net/spip.php?page=backend.xslt" ?>
<rss version="2.0" 
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>

<channel xml:lang="fr">
	<title>SPIP</title>
	<link>https://www.spip.net/</link>
	<description>Syst&#232;me de Publication pour Internet</description>
	<language>fr</language>
	<generator>SPIP - www.spip.net</generator>
	<atom:link href="https://www.spip.net/spip.php?id_auteur=521&amp;page=backend" rel="self" type="application/rss+xml" />

	<image>
		<title>SPIP</title>
		<url>https://www.spip.net/local/cache-vignettes/L144xH107/siteon0-0ecda.png?1615902774</url>
		<link>https://www.spip.net/</link>
		<height>107</height>
		<width>144</width>
	</image>



<item xml:lang="fr">
		<title>#URL_ECRIRE</title>
		<link>https://www.spip.net/fr_article5566.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article5566.html</guid>
		<dc:date>2012-12-15T23:55:00Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum., Pierre KUHN</dc:creator>


		<dc:subject>SPIP 1.9</dc:subject>
		<dc:subject>#URL_ECRIRE</dc:subject>

		<description>
&lt;p&gt;La balise #URL_ECRIRE fabrique l'URL d'un script de l'espace priv&#233; s'il existe. &lt;br class='autobr' /&gt; Cette balise permet d'&#233;crire des liens vers les scripts ?exec de l'espace priv&#233;. &lt;br class='autobr' /&gt;
Ainsi, [&lt;a href=&#034;(#URL_ECRIREunscript)&#034;&gt; ... &lt;/a&gt;] va appeler /ecrire ?exec=unscript. &lt;br class='autobr' /&gt;
Si le script n'existe pas (c'est-&#224;-dire s'il n'existe pas de fichier du nom indiqu&#233;, dans les r&#233;pertoires exec connus de SPIP et des plugins install&#233;s), cette balise ne retourne rien, et cons&#233;quemment tout l'extrait de (&#8230;)&lt;/p&gt;


-
&lt;a href="https://www.spip.net/fr_rubrique543.html" rel="directory"&gt;Balises&lt;/a&gt;

/ 
&lt;a href="https://www.spip.net/@spip19" rel="tag"&gt;SPIP 1.9&lt;/a&gt;, 
&lt;a href="https://www.spip.net/@url_ecrire" rel="tag"&gt;#URL_ECRIRE&lt;/a&gt;

		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;La balise &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;#URL_ECRIRE&lt;/code&gt; fabrique l'URL d'un script de l'espace priv&#233; &lt;i&gt;s'il existe&lt;/i&gt;.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;p&gt;Cette balise permet d'&#233;crire des liens vers les scripts &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;?exec&lt;/code&gt; de l'espace priv&#233;.&lt;/p&gt;
&lt;p&gt;Ainsi, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;[&lt;a href=&#034;(#URL_ECRIRE{unscript})&#034;&gt; ... &lt;/a&gt;]&lt;/code&gt; va appeler &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;/ecrire?exec=unscript&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si le script n'existe pas (c'est-&#224;-dire s'il n'existe pas de fichier du nom indiqu&#233;, dans les r&#233;pertoires &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;exec&lt;/code&gt; connus de SPIP et des plugins install&#233;s), cette balise ne retourne rien, et cons&#233;quemment tout l'extrait de squelette ci-dessus retournera la cha&#238;ne vide. C'est tr&#232;s pratique pour ne produire un lien que si le plugin qui y r&#233;pond est install&#233;.&lt;/p&gt;
&lt;p&gt;Il est possible de compl&#233;ter l'URL par une Query-String, en la donnant en deuxi&#232;me argument &#224; la balise :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;spip&#034; class='spip_code spip_code_block language-spip' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;#URL_ECRIRE{formulaires_voir,id_formulaire=#ID_FORMULAIRE} &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;S'il y a besoin de passer plus d'un param&#232;tre, ou peut aussi faire appel au filtre &lt;a href='https://www.spip.net/fr_article4255.html' class=&#034;spip_in&#034;&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;parametre_url&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sans aucun argument, cette balise retourne l'URL de la page d'accueil de l'espace priv&#233;.&lt;/p&gt;
&lt;p&gt;Pour des informations sur &lt;i&gt;&#233;crire&lt;/i&gt; &lt;a href='https://www.spip.net/fr_article3497.html' class=&#034;spip_in&#034;&gt;&#201;tendre SPIP&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pour g&#233;n&#233;rer une URL de l'espace public, on utilisera &lt;a href='https://www.spip.net/fr_article4630.html' class=&#034;spip_in&#034;&gt;#URL_PAGE&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Mutualisation : un SPIP pour plusieurs sites</title>
		<link>https://www.spip.net/fr_article3811.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article3811.html</guid>
		<dc:date>2010-07-08T22:30:11Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum., Matthieu Marcillaud</dc:creator>



		<description>&lt;p&gt;Proc&#233;dure pour partager le noyau de SPIP entre plusieurs sites.&lt;/p&gt;

-
&lt;a href="https://www.spip.net/fr_rubrique469.html" rel="directory"&gt;Autres fonctions avanc&#233;es&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;Partager les fichiers de SPIP entre plusieurs sites, ce que l'on appelle une mutualisation, permet un gain d'espace disque important, ainsi qu'une possibilit&#233; de mise &#224; jour de SPIP simple de l'ensemble des sites en ne mettant &#224; jour que le noyau.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;!--sommaire--&gt;&lt;div class=&#034;well nav-sommaire nav-sommaire-8&#034; id=&#034;nav6a10dbd3241624.62905864&#034;&gt;
&lt;h2&gt;Sommaire&lt;/h2&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a id=&#034;s-Le-concept&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Le-concept&#034; class=&#034;spip_ancre&#034;&gt;Le concept...&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Initialisation-de-la-mutualisation&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Initialisation-de-la-mutualisation&#034; class=&#034;spip_ancre&#034;&gt;Initialisation de la mutualisation&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Mutualiser-des-domaines-ou-des-sous-domaines&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Mutualiser-des-domaines-ou-des-sous-domaines&#034; class=&#034;spip_ancre&#034;&gt;Mutualiser des domaines ou des sous-domaines&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Mutualiser-les-repertoires-d-un-domaine&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Mutualiser-les-repertoires-d-un-domaine&#034; class=&#034;spip_ancre&#034;&gt;Mutualiser les r&#233;pertoires d'un domaine&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Prefixe-des-tables&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Prefixe-des-tables&#034; class=&#034;spip_ancre&#034;&gt;Pr&#233;fixe des tables&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Fichier-config-mes_options-php&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Fichier-config-mes_options-php&#034; class=&#034;spip_ancre&#034;&gt;Fichier config/mes_options.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Configurer-Apache-pour-les-domaines-et-sous-domaines&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Configurer-Apache-pour-les-domaines-et-sous-domaines&#034; class=&#034;spip_ancre&#034;&gt;Configurer Apache pour les domaines et sous-domaines&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Note-sur-les-sauvegardes-et-les-restaurations&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Note-sur-les-sauvegardes-et-les-restaurations&#034; class=&#034;spip_ancre&#034;&gt;Note sur les sauvegardes et les restaurations&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;!--/sommaire--&gt;&lt;p&gt;SPIP permet de mutualiser ses fichiers. &lt;br class='autobr' /&gt;
(les restaurations peuvent se r&#233;aliser d'un SPIP &#224; l'autre comme s'il n'&#233;tait pas mutualis&#233;).&lt;/p&gt;
&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Le-concept&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Le-concept'&gt;Le concept...&lt;a class='sommaire-back sommaire-back-8' href='#s-Le-concept' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les dossiers n&#233;cessaires au fonctionnement du noyau SPIP (ecrire, prive, squelettes-dist), et ceux marquant l'activit&#233; d'un site (config, IMG, tmp, local) sont clairement identifiables et s&#233;par&#233;s. &lt;br class='autobr' /&gt;
C'est cette s&#233;paration qui permet d'avoir plusieurs sites SPIP autonomes pour un m&#234;me noyau de SPIP.&lt;/p&gt;
&lt;p&gt;Cette autonomie repose sur quatre r&#233;pertoires par site dans lesquels SPIP va &#233;crire les donn&#233;es r&#233;sultant de l'activit&#233; du site. On distingue les donn&#233;es temporaires et permanentes d'une part, et les donn&#233;es accessibles par HTTP et celles qui ne le sont pas d'autre part. Les deux r&#233;pertoires inaccessibles par HTTP seront prot&#233;g&#233;s par un .htaccess install&#233; automatiquement par SPIP (les administrateurs du serveur peuvent mettre ces r&#233;pertoires en dehors de l'arborescence servie par HTTP).&lt;/p&gt;
&lt;p&gt;Ces quatre r&#233;pertoires sont distincts et nomm&#233;s par les constantes PHP suivantes :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;define('_NOM_TEMPORAIRES_INACCESSIBLES', &#034;tmp/&#034;); define('_NOM_TEMPORAIRES_ACCESSIBLES', &#034;local/&#034;); define('_NOM_PERMANENTS_INACCESSIBLES', &#034;config/&#034;); define('_NOM_PERMANENTS_ACCESSIBLES', &#034;IMG/&#034;); &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dans une installation simple de SPIP, ces r&#233;pertoires sont cr&#233;&#233;s &#224; la racine du site avec les valeurs par d&#233;faut ci-dessus.&lt;br class='autobr' /&gt;
La mutualisation des sources de SPIP repose sur l'association de quatre r&#233;pertoires sp&#233;cifiques &#224; chaque site, d&#233;duits de leurs URL.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Initialisation-de-la-mutualisation&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Initialisation-de-la-mutualisation'&gt;Initialisation de la mutualisation&lt;a class='sommaire-back sommaire-back-8' href='#s-Initialisation-de-la-mutualisation' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Cette association est effectu&#233;e par une fonction,&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_initialisation&lt;/code&gt;. Elle admet quatre arguments indiquant la localisation des quatre r&#233;pertoires fondamentaux, et construit &#224; partir de ceux-ci les constantes servant au fonctionnement de SPIP.&lt;br class='autobr' /&gt;
Dans une installation simple, ces quatre arguments sont les quatre constantes ci-dessus. La fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_initialisation&lt;/code&gt; est appel&#233;e juste apr&#232;s le chargement de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;mes_options.php&lt;/code&gt;, &lt;br class='autobr' /&gt;
et refuse silencieusement de s'ex&#233;cuter si elle a d&#233;j&#224; &#233;t&#233; appel&#233;e.&lt;br class='autobr' /&gt;
En cons&#233;quence, si dans ce fichier cette &lt;br class='autobr' /&gt;
fonction est appliqu&#233;e sur des arguments diff&#233;rents d&#233;duits de l'URL du site, on aura autant d'utilisation des sources de SPIP que d'URL de site.&lt;br class='autobr' /&gt;
On peut aussi d&#233;finir dans ce fichier les constantes servant au fonctionnement de SPIP, ces d&#233;finitions ayant priorit&#233; sur celles qu'essaiera de d&#233;finir &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_initialisation&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le code ci-dessous, plac&#233; dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config/mes_options.php&lt;/code&gt; prend le nom de domaine et ex&#233;cute une mutualisation sur les quatre r&#233;pertoires &lt;i&gt;tmp, local, config&lt;/i&gt; et &lt;i&gt;IMG&lt;/i&gt; plac&#233;s dans le dossier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sites/nom_du_domaine/&lt;/code&gt;. &lt;br class='autobr' /&gt;
Auparavant, la d&#233;finition de quelques constantes permet de centraliser les fichiers de journalisation de tous les sites dans un unique r&#233;pertoire, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;log&lt;/code&gt;, et non dans &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sites/nom_du_domaine/tmp/&lt;/code&gt; pour chacun. Cette centralisation n'a rien d'obligatoire mais se r&#233;v&#232;le utile ; elle peut s'appliquer aussi aux r&#233;pertoires d'aide et de sauvegarde.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;&lt;?php $rep = 'sites/'; $site = $_SERVER['HTTP_HOST']; $path = _DIR_RACINE . $rep . $site . '/'; // ordre de recherche des chemins define('_SPIP_PATH', $path . ':' . _DIR_RACINE .':' . _DIR_RACINE .'squelettes-dist/:' . _DIR_RACINE .'prive/:' . _DIR_RESTREINT); // ajout du dossier squelette if (is_dir($path . 'squelettes')) $GLOBALS['dossier_squelettes'] = $rep . $site . '/squelettes'; // exemple de logs a la racine pour tous les sites define('_FILE_LOG_SUFFIX', '_' . $site . '.log'); define('_DIR_LOG', _DIR_RACINE . 'log/'); // prefixes des cookie et des tables : $cookie_prefix = str_replace('.', '_', $site); $table_prefix = 'spip'; // exectution du fichier config/mes_option.php du site mutualise if (is_readable($f = $path . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php')) include($f); // demarrage du site spip_initialisation( ($path . _NOM_PERMANENTS_INACCESSIBLES), ($path . _NOM_PERMANENTS_ACCESSIBLES), ($path . _NOM_TEMPORAIRES_INACCESSIBLES), ($path . _NOM_TEMPORAIRES_ACCESSIBLES) ); ?&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Mutualiser-des-domaines-ou-des-sous-domaines&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Mutualiser-des-domaines-ou-des-sous-domaines'&gt;Mutualiser des domaines ou des sous-domaines&lt;a class='sommaire-back sommaire-back-8' href='#s-Mutualiser-des-domaines-ou-des-sous-domaines' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour mutualiser plusieurs domaines ou sous-domaines, vous devez tous les diriger vers le r&#233;pertoire physique contenant SPIP. Par exemple, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://example.org/&lt;/code&gt;, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://example.net/&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://sous_domaine.example.net/&lt;/code&gt;, pour les mutualiser, doivent tous pointer sur le m&#234;me r&#233;pertoire, comme &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;/var/www/spip/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ce dossier contient donc SPIP ainsi qu'un fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config/mes_options.php&lt;/code&gt; pour activer la mutualisation. En reprenant l'exemple de code donn&#233; au dessus, il faudra alors cr&#233;er les dossiers &lt;i&gt;sites&lt;/i&gt; et &lt;i&gt;log&lt;/i&gt; ainsi que &lt;i&gt;sites/example.org&lt;/i&gt;, &lt;i&gt;sites/example.net&lt;/i&gt; et &lt;i&gt;sites/sous_domaine.example.net&lt;/i&gt; avec dans chacun d'eux les r&#233;pertoires &lt;i&gt;config, local, IMG&lt;/i&gt; et &lt;i&gt;tmp&lt;/i&gt; accessibles en &#233;criture. Il n'y a rien d'autre &#224; r&#233;aliser. En allant sur l'un des sites, SPIP devrait vous proposer son installation.&lt;/p&gt;
&lt;p&gt;Si vous souhaitez pouvoir activer des types d'url diff&#233;rents, comme les &#171; url arborescentes &#187; ou les &#171; url propres &#187;, il sera n&#233;cessaire de cr&#233;er un fichier d'acc&#232;s Http, qui est fourni dans la distribution sous le nom de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;htaccess.txt&lt;/code&gt; : il suffit de le renommer en &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.htaccess&lt;/code&gt; pour le mettre en &#339;uvre. Il s'appliquera &#224; tous les sites mutualis&#233;s, mais il est possible d'avoir des acc&#232;s diff&#233;renci&#233;s en configurant astucieusement le serveur (voir plus bas). Dans les deux cas,&lt;br class='autobr' /&gt;
tout cela ne fonctionnera que si votre serveur accepte d'ex&#233;cuter toutes les directives pr&#233;sentes dans ce fichier, notamment celles concernant&lt;br class='autobr' /&gt;
la r&#233;&#233;criture d'url (&#171; url rewriting &#187;).&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Mutualiser-les-repertoires-d-un-domaine&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Mutualiser-les-repertoires-d-un-domaine'&gt;Mutualiser les r&#233;pertoires d'un domaine&lt;a class='sommaire-back sommaire-back-8' href='#s-Mutualiser-les-repertoires-d-un-domaine' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Chaque dossier (virtuel) d'un domaine, en analysant correctement l'URL, peut aussi devenir un site SPIP mutualis&#233;. Il faut pour cela que l'URL du dossier soit redirig&#233;e de fa&#231;on transparente vers la racine du SPIP. C'est le r&#244;le du fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.htaccess&lt;/code&gt; modifi&#233;. Ainsi &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://example.com/premier_site/&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://example.com/second_site/&lt;/code&gt; peuvent &#234;tre chacun des sites SPIP mutualis&#233;s (et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://example.com/&lt;/code&gt; aussi).&lt;/p&gt;
&lt;p&gt;Dans un premier temps, il faut renommer le fichier &lt;i&gt;htaccess.txt&lt;/i&gt; en &lt;i&gt;.htaccess&lt;/i&gt; et le modifier pour indiquer que les r&#233;pertoires qui sont virtuels doivent pointer &#224; la racine de SPIP. Pour cela, ajouter dans la partie &#171; R&#233;glages personnalis&#233;s &#187; soit le code g&#233;n&#233;rique qui traite tous les r&#233;pertoires virtuels (mais &lt;i&gt;&lt;a href=&#034;http://example.com/premier_site&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.com/premier_site&lt;/a&gt;&lt;/i&gt; sans / final renverra une erreur), soit un code indiquant les noms des dossiers (pas d'erreur si aucun / final) :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;// code g&#233;n&#233;rique RewriteCond %{REQUEST_URI} !^/(config|ecrire|IMG|prive|plugins|plugins-dist|sites|squelettes-dist|squelettes|tmp|lib|local|mutualisation)/(.*) RewriteRule ^[^/]+/(.*) /$1 [QSA,L] // OU code sp&#233;cifique RewriteRule ^(premier_site|second_site)$ /$1/ [R,L] RewriteRule ^(premier_site|second_site)/(.*) /$2 [QSA,L] &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dans un second temps, il faut cr&#233;er une mutualisation en analysant dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config/mes_options.php&lt;/code&gt; l'url transmise. Voici un exemple pour avoir les sites mutualis&#233;s dans &lt;i&gt;sites/exemple.com&lt;/i&gt;, &lt;i&gt;sites/premier_site&lt;/i&gt; et &lt;i&gt;sites/second_site&lt;/i&gt; :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;&lt;?php if ( ( preg_match(',^/([\.a-zA-Z0-9_-]+)/,', $_SERVER['REQUEST_URI'], $r) AND !is_dir(_DIR_RACINE . $r[1]) ) ) { $site = $r[1]; } else { $site = $_SERVER['HTTP_HOST']; } $rep = 'sites/'; $path = _DIR_RACINE . $rep . $site . '/'; // ordre de recherche des chemins define('_SPIP_PATH', $path . ':' . _DIR_RACINE .':' . _DIR_RACINE .'squelettes-dist/:' . _DIR_RACINE .'prive/:' . _DIR_RESTREINT); // ajout du dossier squelette if (is_dir($path . 'squelettes')) $GLOBALS['dossier_squelettes'] = $rep . $site . '/squelettes'; // prefixes des cookie et des tables : $cookie_prefix = str_replace('.', '_', $site); $table_prefix = 'spip'; // exectution du fichier config/mes_option.php du site mutualise if (is_readable($f = $path . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php')) include($f); // demarrage du site spip_initialisation( ($path . _NOM_PERMANENTS_INACCESSIBLES), ($path . _NOM_PERMANENTS_ACCESSIBLES), ($path . _NOM_TEMPORAIRES_INACCESSIBLES), ($path . _NOM_TEMPORAIRES_ACCESSIBLES) ); ?&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Prefixe-des-tables&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Prefixe-des-tables'&gt;Pr&#233;fixe des tables&lt;a class='sommaire-back sommaire-back-8' href='#s-Prefixe-des-tables' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les exemples pr&#233;sent&#233;s n&#233;cessitent autant de bases de donn&#233;es que de sites mutualis&#233;s. Cependant, il est possible d'installer tous les sites dans une m&#234;me base de donn&#233;es, en pr&#233;fixant les noms de leurs tables d'un pr&#233;fixe unique.&lt;/p&gt;
&lt;p&gt;L'exemple ci-dessous cr&#233;e un pr&#233;fixe de 8 caract&#232;res : un pr&#233;fixe avec les 4 premi&#232;res lettres du site, suivi de 4 autres caract&#232;res.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;$table_prefix = substr(str_replace('.', '_', $site),0,4) . substr(md5($site),0,4); &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Fichier-config-mes_options-php&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Fichier-config-mes_options-php'&gt;Fichier config/mes_options.php&lt;a class='sommaire-back sommaire-back-8' href='#s-Fichier-config-mes_options-php' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Toute modification du fichier &lt;i&gt;config/mes_options.php&lt;/i&gt; du noyau SPIP affectera les options de tous les sites h&#233;berg&#233;s.&lt;/p&gt;
&lt;p&gt;Par exemple, mettre dans ce fichier :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$type_urls = 'propres' ;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;donnera par d&#233;faut &#224; tous les sites ce type d'URL... Mais chaque site peut le changer dans son propre &lt;i&gt;/sites/repertoire_du_site/config/mes_options.php&lt;/i&gt;.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Configurer-Apache-pour-les-domaines-et-sous-domaines&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Configurer-Apache-pour-les-domaines-et-sous-domaines'&gt;Configurer Apache pour les domaines et sous-domaines&lt;a class='sommaire-back sommaire-back-8' href='#s-Configurer-Apache-pour-les-domaines-et-sous-domaines' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La mutualisation c&#244;t&#233; serveur, pour ce qui concerne la gestion des sous-domaines ou des domaines reste simple. Il suffit de cr&#233;er une redirection entre le nom de domaine et le r&#233;pertoire physique o&#249; est stock&#233; SPIP.&lt;/p&gt;
&lt;p&gt;Voici un exemple de configuration (minimale) pour un serveur nomm&#233; 'exemple.tld' utilisant des sous-domaines. Le fichier de configuration est &#224; cr&#233;er dans &lt;i&gt;/etc/apache2/sites_availables/exemple.tld&lt;/i&gt;, qu'il faut ensuite activer&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sudo a2ensite exemple.tld sudo /etc/init.d/apache2 reload &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;SPIP est install&#233; dans cet exemple dans '/var/www/spip/'.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;&lt;VirtualHost *&gt; ServerName exemple.tld ServerAdmin webmaster@localhost ServerAlias *.exemple.tld DocumentRoot /var/www/spip/ &lt;Directory /var/www/spip/&gt; Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all &lt;/Directory&gt; &lt;/VirtualHost&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Si vous voulez en plus avoir des fichiers d'acc&#232;s diff&#233;renci&#233;s, il suffit d'utiliser la directive &lt;i&gt;AccessFileName&lt;/i&gt; &#224; l'int&#233;rieur de la directive &lt;br class='autobr' /&gt;
&lt;i&gt;VirtualHost&lt;/i&gt;, de sorte que le fichier d'acc&#232;s du site &lt;i&gt;S&lt;/i&gt; se nomme par exemple &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.htaccess-&lt;/code&gt;&lt;i&gt;S&lt;/i&gt;.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Note-sur-les-sauvegardes-et-les-restaurations&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Note-sur-les-sauvegardes-et-les-restaurations'&gt;Note sur les sauvegardes et les restaurations&lt;a class='sommaire-back sommaire-back-8' href='#s-Note-sur-les-sauvegardes-et-les-restaurations' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Chaque site copie par d&#233;faut ses fichiers de sauvegardes dans le r&#233;pertoire&lt;br class='autobr' /&gt;
&lt;i&gt;/sites/premier_site/tmp/dump&lt;/i&gt; (ou &lt;i&gt;/sites/premier_site/tmp/upload/login&lt;/i&gt; pour les sauvegardes d'un administrateur restreint).&lt;/p&gt;
&lt;p&gt;Les restaurations se font par le m&#234;me dossier. Le chemin des images est aussi correctement pris en compte .&lt;/p&gt;&lt;/section&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Les auto-r&#233;f&#233;rences multilingues de la documentation</title>
		<link>https://www.spip.net/fr_article4040.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article4040.html</guid>
		<dc:date>2009-03-22T22:32:17Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum.</dc:creator>



		<description>&lt;p&gt;Cet article explique pourquoi il faut syst&#233;matiquement utiliser le raccourci &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;[{}-&gt;artN]&lt;/code&gt;, ou plus simplement &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;[{}-&gt;N]&lt;/code&gt;, pour r&#233;f&#233;rencer l'article N de la documentation quelles que soient les langues de l'article appel&#233; et du texte appelant.&lt;/p&gt;

-
&lt;a href="https://www.spip.net/fr_rubrique275.html" rel="directory"&gt;Traduire&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;p&gt;Les r&#233;dacteurs de la documentation doivent imp&#233;rativement utiliser la notation &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;[{}-&gt;artN]&lt;/code&gt; pour r&#233;f&#233;rencer l'article N de la documentation, et les traducteurs peuvent recopier ce raccourci sans plus avoir &#224; le modifier un jour. En effet, si l'article N n'existe pas dans la langue du texte qui utilise ce raccourci, celui-ci produira l'URL de l'article N (ce qui est le mieux que l'on puisse faire), mais si une traduction existe, ce sera automatiquement l'URL de cette traduction qui sera produite. Plus pr&#233;cis&#233;ment, ce comportement sera strictement observ&#233; lors d'une r&#233;f&#233;rence &#224; partir de l'espace priv&#233;, tandis que dans l'espace public on ajoute la contrainte suppl&#233;mentaire que la traduction soit publi&#233;e, afin de produire une URL disponible &#224; coup s&#251;r.&lt;/p&gt;
&lt;p&gt;Comment est-ce possible ? SPIP interpr&#232;te une paire d'accolades vides comme un &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;hreflang&lt;/code&gt; &#233;gal &#224; la langue du texte o&#249; figure le raccourci. La surcharge introduite pour ce site consiste simplement &#224; chercher si l'article d&#233;sign&#233; par le raccourci existe dans la langue indiqu&#233;e par le &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;hreflang&lt;/code&gt;. Si c'est le cas, le raccourci &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;-&gt;artN&lt;/code&gt; est remplac&#233; par &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;-&gt;artP&lt;/code&gt;, o&#249; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;P&lt;/code&gt; est la traduction de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;N&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Les bases de donn&#233;es en SPIP</title>
		<link>https://www.spip.net/fr_article3681.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article3681.html</guid>
		<dc:date>2008-12-12T21:45:47Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum.</dc:creator>



		<description>&lt;p&gt;Tout ce que SPIP sait faire avec des bases de donn&#233;es&lt;/p&gt;

-
&lt;a href="https://www.spip.net/fr_rubrique472.html" rel="directory"&gt;Bases de donn&#233;es&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;SPIP peut &#234;tre vu comme un outil de mise en page dans un format MIME (HTML, RSS, ICS ...) d'extraits de bases de donn&#233;es.&lt;br class='autobr' /&gt;
SPIP peut rassembler dans une page des donn&#233;es en provenance de plusieurs bases SQL, accessibles par des serveurs &#233;ventuellement diff&#233;rents et distants les uns des autres. SPIP se charge de g&#233;rer les diff&#233;rentes connexions et d&#233;clarations de tables sans imposer de programmation &#224; ses utilisateurs. Le pr&#233;sent article expose ces manipulations de bases de donn&#233;es.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;!--sommaire--&gt;&lt;div class=&#034;well nav-sommaire nav-sommaire-6&#034; id=&#034;nav6a10dbd327f6c2.90207779&#034;&gt;
&lt;h2&gt;Sommaire&lt;/h2&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a id=&#034;s-Installation-minimale&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Installation-minimale&#034; class=&#034;spip_ancre&#034;&gt;Installation minimale&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Complements-d-installation&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Complements-d-installation&#034; class=&#034;spip_ancre&#034;&gt;Compl&#233;ments d'installation&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Installations-croisees&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Installations-croisees&#034; class=&#034;spip_ancre&#034;&gt;Installations crois&#233;es&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Les-bases-supplementaires-sous-SPIP&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Les-bases-supplementaires-sous-SPIP&#034; class=&#034;spip_ancre&#034;&gt;Les bases suppl&#233;mentaires sous SPIP&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Sauvegardes-et-Fusions&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Sauvegardes-et-Fusions&#034; class=&#034;spip_ancre&#034;&gt;Sauvegardes et Fusions&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Un-exemple-complet&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Un-exemple-complet&#034; class=&#034;spip_ancre&#034;&gt;Un exemple complet&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;!--/sommaire--&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Installation-minimale&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Installation-minimale'&gt;Installation minimale&lt;a class='sommaire-back sommaire-back-6' href='#s-Installation-minimale' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici d'abord tous les sc&#233;narios possibles d'installation de SPIP avec une seule base.&lt;/p&gt;
&lt;p&gt;Lors de l'installation de SPIP, celui-ci teste la configuration de PHP et propose, lorsque c'est possible, un choix parmi plusieurs types de serveurs SQL (actuellement MySQL ou SQLite), qui offrent tous les m&#234;mes fonctionnalit&#233;s. &#192; ce stade, il faut &#233;galement fournir l'adresse Internet du serveur SQL, un identifiant de connexion &#224; ce serveur et son mot de passe associ&#233;. Ces informations sont en g&#233;n&#233;ral &#224; saisir dans le formulaire d'installation et sont sauv&#233;es dans un fichier qui par d&#233;faut est &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config/connect.php&lt;/code&gt;. Toutefois, si vous voulez mettre en &#339;uvre la &lt;a href='https://www.spip.net/fr_article3514.html' class=&#034;spip_in&#034;&gt;Mutualisation du noyau SPIP&lt;/a&gt;, vous pouvez indiquer une ou plusieurs de ces valeurs dans le fichier de configuration &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;mes_options.php&lt;/code&gt;. SPIP ne les demandera alors pas, ce qui dispense de les saisir et ne vous oblige pas &#224; les communiquer &#224; ceux qui utiliseront votre installation mutualis&#233;e.&lt;br class='autobr' /&gt;
Voici les noms des constantes PHP &#224; d&#233;finir pour cela :&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_SERVER_DB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;type du serveur SQL&lt;/i&gt; (Mysql ou PG ; casse indiff&#233;rente)&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_HOST_DB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt; nom Internet du serveur SQL (par exemple : localhost)&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_USER_DB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;un nom d'utilisateur du serveur SQL&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_PASS_DB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;son mot de passe&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SPIP se connecte alors au serveur choisi, avec les identifiants de connexion.&lt;br class='autobr' /&gt;
En cas de r&#233;ussite, il teste si l'utilisateur a le droit de cr&#233;er des bases, ou seulement le droit de voir celles pr&#233;sentes et d'en choisir une, voire n'a le droit que d'utiliser une base homonyme de son nom d'utilisateur. Vous pouvez &#233;galement fixer d'avance dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;mes_options.php&lt;/code&gt; le nom de la base de donn&#233;es &#224; utiliser, en d&#233;finissant la constante PHP :&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_NAME_DB&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;i&gt;nom de la base&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SPIP poursuit alors l'installation en cr&#233;ant ses tables SQL (ou, en cas de r&#233;installation, en v&#233;rifiant que celles pr&#233;sentes sont utilisables). Ces tables commencent toutes par un &lt;i&gt;pr&#233;fixe de table&lt;/i&gt; (qui vaut par d&#233;faut &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_&lt;/code&gt;) et peut &#234;tre indiqu&#233; dans &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;mes_options.php&lt;/code&gt; de deux mani&#232;res :&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;&lt;i&gt;la variable globale&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$table_prefix&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;&lt;i&gt;la constante&lt;/i&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_INSTALL_TABLE_PREFIX&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ce pr&#233;fixe de table est ce qui permet d'&#233;crire des boucles abr&#233;g&#233;es dans les squelettes, comme &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;&lt;BOUCLE1(ARTICLES)....&lt;/code&gt; alors que le nom SQL de la table est en fait &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_articles&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;SPIP demande ensuite de cr&#233;er le premier utilisateur du site en fournissant un nom et un mot de passe (sans rapport avec ceux du serveur SQL) ou en proposant de d&#233;l&#233;guer le service d'authentification &#224; un serveur LDAP. Apr&#232;s cette d&#233;claration, la proc&#233;dure minimale d'installation est termin&#233;e, et la page suivante est la page habituelle d'entr&#233;e dans l'espace de r&#233;daction, qui demande les identifiants venant d'&#234;tre saisis.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Complements-d-installation&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Complements-d-installation'&gt; Compl&#233;ments d'installation&lt;a class='sommaire-back sommaire-back-6' href='#s-Complements-d-installation' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici &#224; pr&#233;sent comment indiquer &#224; SPIP plusieurs bases &#224; exploiter, sous le m&#234;me serveur ou sous des serveurs diff&#233;rents, et m&#234;me sur des machines diff&#233;rentes.&lt;/p&gt;
&lt;p&gt;Une fois le site install&#233;, choisir le sous-menu &lt;i&gt;maintenance du site&lt;/i&gt; dans le menu &lt;i&gt;configuration&lt;/i&gt; en haut de l'espace priv&#233;. Ce menu fournit une page &#224; trois onglets ; cliquer sur celui de droite, nomm&#233; &lt;i&gt;d&#233;clarer une autre base&lt;/i&gt;.&lt;br class='autobr' /&gt;
On acc&#232;de alors &#224; un formulaire quasiment identique au formulaire d'installation : il propose d'indiquer un type de serveur SQL, son adresse Internet, un nom d'utilisateur et son mot de passe. En cas de connexion r&#233;ussie, SPIP demandera de fournir le nom d'une base, en listant celles pr&#233;sentes s'il en a la possibilit&#233;. Si elle existe bien, il cr&#233;era un fichier de connexion suppl&#233;mentaire, qui par d&#233;faut se trouve dans le r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config&lt;/code&gt; et porte le nom de la base de donn&#233;es indiqu&#233;e.&lt;/p&gt;
&lt;p&gt;Cela fait, SPIP revient &#224; nouveau &#224; ce formulaire, et liste les fichiers de connexion pr&#233;sents, autrement dit les bases accessibles. SPIP propose donc de d&#233;clarer encore une base suppl&#233;mentaire : il n'y a pas de limitation au nombre de bases d&#233;clarables.&lt;/p&gt;
&lt;p&gt;L'int&#233;r&#234;t de ces d&#233;clarations est de pouvoir appliquer la notation des squelettes de mise en pages &#224; ces bases suppl&#233;mentaires. S'il existe un fichier de connexion nomm&#233; &lt;i&gt;B&lt;/i&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.php&lt;/code&gt;, permettant d'interroger une base poss&#233;dant une table nomm&#233;e &lt;i&gt;T&lt;/i&gt;, alors le squelette &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;&lt;BOUCLE1(B:T) /&gt;#TOTAL_BOUCLE&lt;//B1&gt;&lt;/code&gt; donnera le nombre de lignes de cette table. De plus, SPIP demande au serveur SQL de lui &lt;i&gt;d&#233;crire&lt;/i&gt; cette table, ce qui lui permet de conna&#238;tre ses champs et, &#233;ventuellement, sa &lt;i&gt;cl&#233; primaire&lt;/i&gt;. Si la boucle &lt;i&gt;T&lt;/i&gt; a une cl&#233; primaire nomm&#233;e &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;id&lt;/code&gt; et un champ nomm&#233; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;nom&lt;/code&gt;, alors le squelette : &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;&lt;BOUCLE1(B:T){id}&gt;#NOM&lt;/BOUCLE1&gt;&lt;/code&gt; donnera le champ &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;nom&lt;/code&gt; de l'unique ligne ayant l'&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;id&lt;/code&gt; donn&#233; par le contexte.&lt;/p&gt;
&lt;p&gt;Enfin, il est possible d'appliquer un squelette en demandant que toutes ses boucles utilisent une autre base que celle par d&#233;faut, en ajoutant dans l'URL de la page le param&#232;tre &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect&lt;/code&gt; indiquant le nom de la base. Par exemple &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;http://monsite?connect=autre_site&lt;/code&gt; appliquera le squelette &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sommaire&lt;/code&gt; standard du site &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;monsite&lt;/code&gt; &#224; la base indiqu&#233;e par le fichier de connexion &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config/autre_site.php&lt;/code&gt; dans le r&#233;pertoire d'installation de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;mon_site&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Il est recommand&#233; de respecter la casse du nom du fichier de connexion, lorsqu'on l'utilise dans une boucle ou comme param&#232;tre de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect&lt;/code&gt; : aucune conversion majuscules / minuscules n'est effectu&#233;e par SPIP (mais certains syst&#232;mes de fichiers le font).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Remarque :&lt;/i&gt; L'acc&#232;s &#224; des bases suppl&#233;mentaires est exclusivement en lecture ; en particulier, si une base est par exemple un forum (administr&#233; par SPIP ou non) il reste impossible de poster dans ce forum autrement qu'&#224; partir de son site d'origine. La lev&#233;e de cette restriction est &#224; l'&#233;tude.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Installations-croisees&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Installations-croisees'&gt;Installations crois&#233;es&lt;a class='sommaire-back sommaire-back-6' href='#s-Installations-croisees' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les extraits de squelette ci-dessus reposent donc sur l'existence d'un fichier de connexion nomm&#233; &lt;i&gt;B&lt;/i&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.php&lt;/code&gt;.&lt;br class='autobr' /&gt;
Un point important est que le fichier de connexion principal et ceux des bases suppl&#233;mentaires ont le m&#234;me format, ce qui permet en particulier &#224; un site SPIP d'utiliser directement le fichier de connexion d'un autre site SPIP pour exploiter ses tables. Une mani&#232;re de proc&#233;der est de copier le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect.php&lt;/code&gt; du site B sous le nom B&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.php&lt;/code&gt; dans le r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config&lt;/code&gt; du site A.&lt;/p&gt;
&lt;p&gt;Une mani&#232;re plus astucieuse, dans le cas de sites partageant une m&#234;me installation de SPIP, est d'avoir un seul r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config&lt;/code&gt; pour tous les sites, et d'y nommer le fichier de connexion du site A non pas &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect.php&lt;/code&gt; mais A&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.php&lt;/code&gt;, de m&#234;me pour le site B etc. De la sorte, d&#232;s qu'un site est install&#233; sous SPIP, il est connu comme base suppl&#233;mentaire de tous les autres sites partageant cette installation de SPIP, et il verra tous les sites utilisant le m&#234;me r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;config&lt;/code&gt; que lui comme autant de bases suppl&#233;mentaires. Pour obtenir cet optimum dans les d&#233;clarations implicites, il faut d&#233;finir soigneusement les constantes &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_CONFIG&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_FILE_CONNECT_INS&lt;/code&gt;. &lt;br class='autobr' /&gt;
On trouvera plus bas un exemple de mutualisation offrant cette fonctionnalit&#233; et quelques autres.&lt;/p&gt;
&lt;p&gt;Pour un site install&#233; sur un serveur SQL &#233;loign&#233;, la copie de son fichier de connexion sur le site local peut suffire en th&#233;orie. Toutefois beaucoup d'h&#233;bergeurs refusent que leurs serveurs SQL soient interrog&#233;s par des machines en dehors de leur r&#233;seau local. Il faut aussi penser que bien souvent le &#171; nom &#187; indiqu&#233; pour le serveur SQL &#224; l'installation est &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;localhost&lt;/code&gt;, qui est une adresse relative au serveur HTTP, alors qu'ici il y a n&#233;cessit&#233; d'une adresse absolue. En bref, SPIP peut op&#233;rer dans une telle architecture, mais un minimum de connaissances, voire d'autorisation d'intervention, sur la topographie des sous-r&#233;seaux en jeu est pratiquement indispensable.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Les-bases-supplementaires-sous-SPIP&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Les-bases-supplementaires-sous-SPIP'&gt; Les bases suppl&#233;mentaires sous SPIP &lt;a class='sommaire-back sommaire-back-6' href='#s-Les-bases-supplementaires-sous-SPIP' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lorsqu'un fichier de connexion est celui d'un autre site sous SPIP (que ce soit une copie ou l'original accessible par installations crois&#233;es), il contient l'indication que ce site est sous SPIP (la globale &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect_version&lt;/code&gt; y est affect&#233;e). Dans ce cas, les squelettes du site principal vont s'appliquer avec un comportement sp&#233;cial :&lt;/p&gt;
&lt;p&gt;- les boucles avec nom abr&#233;g&#233; seront interpr&#233;t&#233;es comme abr&#233;g&#233;es aussi dans la base suppl&#233;mentaire ; autrement dit, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;&lt;BOUCLE1(B:ARTICLES)...&lt;/code&gt; (ou &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;&lt;BOUCLE1(ARTICLES)...&lt;/code&gt; avec une URL comportant &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect=B.&lt;/code&gt;) r&#233;f&#233;rencera la table &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_articles&lt;/code&gt; dans la base B, plus pr&#233;cis&#233;ment la table &lt;i&gt;prefixe&lt;/i&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;articles&lt;/code&gt; o&#249; &lt;i&gt;prefixe&lt;/i&gt; est celui utilis&#233; par le site B (ce pr&#233;fixe est indiqu&#233; dans le fichier de connexion) ;&lt;/p&gt;
&lt;p&gt;- &#224; l'int&#233;rieur d'une boucle, les balises &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;#URL_&lt;/code&gt; (voir &lt;a href='https://www.spip.net/fr_article765.html' class=&#034;spip_in&#034;&gt;Utiliser des URLs personnalis&#233;es&lt;/a&gt;) utiliseront le type d'URL du site principal, et non du site distant, et l'URL produite r&#233;f&#233;rencera le site principal par &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect=&lt;/code&gt;&lt;i&gt;site_distant&lt;/i&gt; ; cette strat&#233;gie permet de naviguer dans la base du site distant sans cesser d'utiliser les squelettes du site principal, autrement dit de tester l'apparence que donne ce jeu de squelettes et son type d'URL sur le site distant sans modifier l'installation de celui-ci ou travailler sur une copie.&lt;/p&gt;
&lt;p&gt;- &lt;a href='https://www.spip.net/fr_article1578.html' class=&#034;spip_in&#034;&gt;Les raccourcis SPIP&lt;/a&gt; des balises #URL qui peuvent figurer dans les champs de la base de donn&#233;es distante sont eux aussi interpr&#233;t&#233;s de cette mani&#232;re : &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;[-&gt;art3681]&lt;/code&gt; r&#233;f&#233;rencera bien l'article 3681 de la base distante, mais &#224; travers une URL qui fournira la mise en page par les squelettes du site principal.&lt;/p&gt;
&lt;p&gt;Ce mode de fonctionnement permet donc de pr&#233;senter d'autres bases SPIP sans m&#234;me avoir &#224; &#233;crire des squelettes de mises en page, puisque les noms des tables dans ceux-ci sont les m&#234;mes que ceux du site distant. En revanche, une base qui n'est pas sous SPIP a besoin de squelettes de mises en page nommant explicitement les tables de cette autre base et ses champs.&lt;br class='autobr' /&gt;
Pour r&#233;pondre &#224; ce besoin, les administrateurs du site b&#233;n&#233;ficient d'un traitement sp&#233;cial : lorsqu'ils donnent &#224; leur navigateur l'URL de leur site suivi de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;?page=table:nom_de_la_table&lt;/code&gt; o&#249; &lt;i&gt;nom_de_la_table&lt;/i&gt; est le nom d'une table de la base (exemple : &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;?page=table:articles&lt;/code&gt;), SPIP va automatiquement construire un squelette sp&#233;cifique &#224; cette table, permettant d'en examiner le contenu avec une grande ergonomie. Le squelette produit est affichable &#224; travers le lien &lt;i&gt;squelette&lt;/i&gt; en bas de page. Il est possible alors de le copier &#224; la souris (cliquer en haut de colonne pour cacher la num&#233;rotation des lignes) et de l'am&#233;liorer en le travaillant sous un &#233;diteur appropri&#233;.&lt;/p&gt;
&lt;p&gt;&#192; noter qu'avec cette production automatique, SPIP pourrait, &#224; la limite, fonctionner sans aucun squelette pr&#233;d&#233;fini.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Sauvegardes-et-Fusions&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Sauvegardes-et-Fusions'&gt; Sauvegardes et Fusions &lt;a class='sommaire-back sommaire-back-6' href='#s-Sauvegardes-et-Fusions' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Avec le sous-menu &lt;strong&gt;maintenance du site&lt;/strong&gt;, SPIP donne acc&#232;s &#224; deux outils de sauvegarde et restauration de la base de donn&#233;es locale (voir &lt;a href='https://www.spip.net/fr_article3418.html' class=&#034;spip_in&#034;&gt;Sauvegarder vos donn&#233;es&lt;/a&gt;). Il est possible d'installer une sauvegarde issue d'un vieux site, dans une installation de SPIP de num&#233;ro de version sup&#233;rieur.&lt;/p&gt;
&lt;p&gt;Le formulaire de sauvegarde propose de limiter la sauvegarde &#224; une rubrique donn&#233;e. Le fichier produit contiendra les articles, sites, br&#232;ves et sous rubriques contenu dans la rubrique indiqu&#233;e, ainsi que les mots-cl&#233;s et groupes de mots-cl&#233;s utilis&#233;s par toutes ces donn&#233;es. Le nom de la sauvegarde sera par d&#233;faut le nom de la rubrique, mais cela peut &#234;tre chang&#233;. La cr&#233;ation des fichiers de sauvegarde peut &#234;tre si longue que le serveur HTTP peut vous d&#233;connecter pour cause d'inactivit&#233; apparente. &lt;br class='autobr' /&gt;
Recharger simplement la page : SPIP retrouvera &#224; quel endroit il en &#233;tait et poursuivra son travail. Le grand nombre de fichiers que vous pourrez temporairement apercevoir dans un sous-r&#233;pertoire du r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;tmp&lt;/code&gt; est normal, car li&#233; &#224; l'anticipation de cette situation de reprise apr&#232;s d&#233;connexion.&lt;/p&gt;
&lt;p&gt;Sym&#233;triquement, le formulaire de restauration propose &#224; pr&#233;sent deux fonctionnalit&#233;s. La premi&#232;re est l'habituel remplacement de la base courante par la base sauvegard&#233;e. La deuxi&#232;me consiste &#224; consid&#233;rer le fichier de sauvegarde comme une base incompl&#232;te venant s'ajouter &#224; la base d&#233;j&#224; install&#233;e. Comme il peut y avoir conflit entre la base install&#233;e et la base incompl&#232;te en ce qui concerne la num&#233;rotation de leurs tables (d'articles, de br&#232;ves etc), SPIP commence par renum&#233;roter les &#233;l&#233;ments de la base incompl&#232;te en leur affectant des num&#233;ros imm&#233;diatement sup&#233;rieurs aux maxima de la base install&#233;e. Dans une deuxi&#232;me passe, SPIP importe effectivement les &#233;l&#233;ments renum&#233;rot&#233;s, mais lors de la premi&#232;re passe, il a compar&#233; les &#233;l&#233;ments &#224; importer avec ceux de la base install&#233;e et a ignor&#233; les doublons d&#233;finis par les r&#232;gles suivantes :&lt;/p&gt;
&lt;p&gt;- s'il existe dans la base install&#233;e un groupe de mots-cl&#233;s de m&#234;me nom qu'un groupe de mots-cl&#233;s &#224; importer, ce groupe est ignor&#233; ;&lt;/p&gt;
&lt;p&gt;- si un mot-cl&#233; dont le groupe de mot-cl&#233;s n'a pas &#233;t&#233; import&#233; poss&#232;de un homonyme dans un groupe de mot-cl&#233;s portant le m&#234;me nom que son groupe d'origine, ce mot-cl&#233; est ignor&#233; ;&lt;/p&gt;
&lt;p&gt;- s'il existe dans la base install&#233;e une rubrique de secteur portant m&#234;me nom qu'une rubrique de secteur &#224; importer, cette rubrique est ignor&#233;e ;&lt;/p&gt;
&lt;p&gt;- si une sous-rubrique dont la rubrique parente n'a pas &#233;t&#233; import&#233;e poss&#232;de un homonyme de m&#234;me parent&#233;, cette sous-rubrique est ignor&#233;e ; il en est de m&#234;me pour les articles, les br&#232;ves et les sites r&#233;f&#233;renc&#233;s ;&lt;/p&gt;
&lt;p&gt;- s'il existe dans la base install&#233;e un document portant m&#234;me nom qu'un document &#224; importer et qu'ils ont m&#234;me taille, ce document est ignor&#233;.&lt;/p&gt;
&lt;p&gt;Dit de mani&#232;re plus synth&#233;tique, l'op&#233;ration de fusion est l'union de deux bases, le contenu de la base install&#233;e ayant priorit&#233; sur la base import&#233;e en ce qui concerne les doublons (par exemple, pour deux secteurs de m&#234;me nom, les champs &lt;i&gt;texte&lt;/i&gt; et &lt;i&gt;descriptif&lt;/i&gt; de celui d&#233;j&#224; install&#233; seront conserv&#233;s et les autres seront ignor&#233;s).&lt;/p&gt;
&lt;p&gt;En ce qui concerne les documents joints, ceux-ci seront import&#233;s en tant que documents distants, ce qui dispense de recenser et copier la partie du r&#233;pertoire IMG/ concern&#233;e par la sauvegarde partielle. On peut ensuite utiliser, sur chaque document, le bouton de copie locale pour s'affranchir du site d'origine. Si celui-ci a d&#233;j&#224; disparu ou poss&#232;de des restrictions d'acc&#232;s non contournables par le site r&#233;cepteur, il faudra installer le r&#233;pertoire IMG/ originel &#224; une URL accessible, et la donner dans la derni&#232;re case de saisie du formulaire d'importation.&lt;/p&gt;
&lt;p&gt;On notera la possibilit&#233; de rabattre les statuts de valeur &lt;i&gt;publi&#233;&lt;/i&gt; &#224; la valeur &lt;i&gt;propos&#233;&lt;/i&gt;, ce qui permet de garder une politique de publication au cas par cas, malgr&#233; cette importation massive.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Un-exemple-complet&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Un-exemple-complet'&gt;Un exemple complet&lt;a class='sommaire-back sommaire-back-6' href='#s-Un-exemple-complet' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;L'installation mutualis&#233;e de SPIP ci-dessous permet d'avoir un seul r&#233;pertoire de configuration (&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_CONNECT&lt;/code&gt;) et un seul de sauvegardes (&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_DUMP&lt;/code&gt;).&lt;br class='autobr' /&gt;
Chaque site peut ainsi donner des aper&#231;us de la base de chacun des autres, et utiliser leurs sauvegardes pour les fusionner avec sa propre base. &lt;br class='autobr' /&gt;
N'est utilis&#233; aussi qu'un seul r&#233;pertoire pour le cache de l'aide en ligne (&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_AIDE&lt;/code&gt;) car SPIP l'importe au coup par coup &#224; partir du serveur &lt;a href=&#034;https://www.spip.net/fr_rubrique91.html&#034;&gt;spipnet&lt;/a&gt;, et un seul r&#233;pertoire pour les &lt;i&gt;Document Type Definitions&lt;/i&gt; que &lt;a href='https://www.spip.net/article3541.html'&gt;article 3541&lt;/a&gt; va chercher sur le site du W3C et autres (&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_XML&lt;/code&gt;).&lt;br class='autobr' /&gt;
Les fichiers de droits et de journalisation sont &#233;galement rassembl&#233;s dans seulement deux r&#233;pertoires (&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_CHMOD&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_DIR_LOG&lt;/code&gt;).&lt;br class='autobr' /&gt;
Seront donc cr&#233;&#233;s &#224; la racine config/connect, config/chmod, tmp/log, tmp/dump, tmp/xml et tmp/aide. Le premier contiendra A.php pour la connexion &#224; la base A, B.php etc.&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;if ( preg_match(',/([a-zA-Z0-9_-]*)[/?],',$_SERVER['REQUEST_URI'],$r)) { if (is_dir($e = _DIR_RACINE . 'Ajouts/' . $r[1]. '/')) { $cookie_prefix = $table_prefix = $r[1]; define('_SPIP_PATH', _DIR_RACINE. 'Ajouts/' . $table_prefix . '/dist/:' . _DIR_RACINE .'Ajouts/' . $table_prefix . '/:' . _DIR_RACINE .'dist/:' . _DIR_RACINE .'dist/javascript/:' . _DIR_RESTREINT); $pi = $e . _NOM_PERMANENTS_INACCESSIBLES; $pa = $e . _NOM_PERMANENTS_ACCESSIBLES; $ti = $e . _NOM_TEMPORAIRES_INACCESSIBLES; $ta = $e . _NOM_TEMPORAIRES_ACCESSIBLES; $pig = _DIR_RACINE . _NOM_PERMANENTS_INACCESSIBLES; $tig = _DIR_RACINE . _NOM_TEMPORAIRES_INACCESSIBLES; define('_DIR_DUMP', $tig . 'dump/'); define('_DIR_AIDE', $tig . 'aide/'); define('_DIR_CACHE_XML', $tig . &#034;xml/&#034;); define('_DIR_LOG', $tig . 'log/'); define('_DIR_CONNECT', $pig . 'connect/'); define('_DIR_CHMOD', $pig . 'chmod/'); define('_FILE_CONNECT_INS', $table_prefix); define('_FILE_CHMOD_INS', $table_prefix); define('_FILE_LOG_SUFFIX', '_' . $table_prefix . '.log'); $GLOBALS['test_dirs'] = array($pa, $ta, $ti, $pig, $tig, _DIR_DUMP, _DIR_LOG, _DIR_CONNECT, _DIR_CHMOD); spip_initialisation($pi, $pa, $ti, $ta); } ) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/section&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>L'interface de SPIP avec SQL</title>
		<link>https://www.spip.net/fr_article3683.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article3683.html</guid>
		<dc:date>2008-12-12T21:45:43Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum.</dc:creator>



		<description>&lt;p&gt;Les fonctions &#224; appeler et les choses &#224; savoir pour &#233;tendre SPIP de mani&#232;re portable quant &#224; son utilisation de SQL.&lt;/p&gt;

-
&lt;a href="https://www.spip.net/fr_rubrique472.html" rel="directory"&gt;Bases de donn&#233;es&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_texte'&gt;&lt;!--sommaire--&gt;&lt;div class=&#034;well nav-sommaire nav-sommaire-3&#034; id=&#034;nav6a10dbd32b0b85.78223918&#034;&gt;
&lt;h2&gt;Sommaire&lt;/h2&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a id=&#034;s-Architecture-generale&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Architecture-generale&#034; class=&#034;spip_ancre&#034;&gt;Architecture g&#233;n&#233;rale&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Fonctions-disponibles&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Fonctions-disponibles&#034; class=&#034;spip_ancre&#034;&gt;Fonctions disponibles&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Realisation-des-portages&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Realisation-des-portages&#034; class=&#034;spip_ancre&#034;&gt;R&#233;alisation des portages&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;!--/sommaire--&gt;&lt;p&gt;Cet article comporte trois parties. Les deux premi&#232;res sont destin&#233;es aux d&#233;veloppeurs d&#233;sireux d'&#233;crire des extensions de SPIP ; elles pr&#233;sentent l'architecture g&#233;n&#233;rale, puis les fonctions disponibles. La troisi&#232;me d&#233;taille l'impl&#233;mentation et est destin&#233;e aux contributeurs de SPIP, d&#233;sireux de le porter sur d'autres impl&#233;mentations de SQL ou d'am&#233;liorer les portages existants. Dans tout l'article, on parlera de &lt;i&gt;serveur SQL&lt;/i&gt; pour d&#233;signer une impl&#233;mentation de SQL utilis&#233;e par SPIP, bien qu'&#224; proprement parler certaines impl&#233;mentations ne sont pas des serveurs.&lt;/p&gt;
&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Architecture-generale&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Architecture-generale'&gt;Architecture g&#233;n&#233;rale&lt;a class='sommaire-back sommaire-back-3' href='#s-Architecture-generale' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dans un premier temps, on peut consid&#233;rer que l'interface de SPIP aux impl&#233;mentations de SQL se r&#233;duit &#224; l'unique fonction suivante, d&#233;finie dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;ecrire/base/abstract_sql.php&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_serveur($ins_sql, $serveur='', $continue=false) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cette fonction commence, si elle ne l'a pas d&#233;j&#224; fait auparavant, par se connecter au serveur sp&#233;cifi&#233; en deuxi&#232;me argument.&lt;br class='autobr' /&gt;
Cet argument est souvent omis, ce qui d&#233;signe alors l'impl&#233;mentation SQL choisie &#224; l'installation, et m&#233;moris&#233; par SPIP dans un &lt;i&gt;fichier de connexion&lt;/i&gt; (voir &lt;a href='https://www.spip.net/fr_article3681.html' class=&#034;spip_in&#034;&gt;Les bases de donn&#233;es en SPIP&lt;/a&gt;).&lt;br class='autobr' /&gt;
Sinon, l'argument doit indiquer explicitement le nom du fichier de connexion &#224; utiliser, l'extension &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;.php&lt;/code&gt; &#233;tant omise. Le r&#233;sultat retourn&#233; est une autre fonction, r&#233;alisant le type d'action demand&#233;e par la cha&#238;ne pass&#233;e en premier argument (par exemple &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;select&lt;/code&gt; ou &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;fetch&lt;/code&gt;) sur la base SQL indiqu&#233;e par le fichier de connexion. &lt;br class='autobr' /&gt;
Le troisi&#232;me argument indique ce qu'il faut faire lorsqu'une telle fonction ne peut &#234;tre retourn&#233;e.&lt;br class='autobr' /&gt;
S'il est absent ou &#233;gal &#224; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;false&lt;/code&gt;, une erreur fatale sera d&#233;clench&#233;e. &lt;br class='autobr' /&gt;
Autrement, deux autres situations sont distingu&#233;es.&lt;br class='autobr' /&gt;
Si la connexion indiqu&#233;e est inconnue ou inop&#233;rante, la valeur &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;false&lt;/code&gt; sera retourn&#233;e.&lt;br class='autobr' /&gt;
Autrement, sera retourn&#233;e une structure de donn&#233;es d&#233;crivant la connexion (elle sera d&#233;crite dans la derni&#232;re partie), ce qui permet d'une part de v&#233;rifier qu'une fonction existe sans risquer l'erreur fatale, et d'autre part d'obtenir plusieurs informations avant utilisation.&lt;/p&gt;
&lt;p&gt;Cette vision minimaliste de l'interface permet de tout faire, mais avec une syntaxe assez opaque. Si par exemple &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$db&lt;/code&gt; est le nom d'une base dans le serveur principal, on ne le s&#233;lectionnera pas&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;$f = sql_serveur('selectdb'); $f($db); &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pour clarifier l'&#233;criture, il existe un jeu de fonctions encha&#238;nant les deux instructions ci-dessus pour les cas les plus fr&#233;quents. Par exemple, il existe&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_selectdb($nom, $serveur='') &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ce qui permet de r&#233;&#233;crire plus simplement l'op&#233;ration pr&#233;c&#233;dente :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_selectdb($db) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;De mani&#232;re g&#233;n&#233;rale, l'interface de SPIP aux serveurs SQL est un jeu de fonctions dont le nom est &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_&lt;/code&gt;&lt;i&gt;f&lt;/i&gt; et dont le dernier argument, optionnel, est le nom du serveur. Elles appellent &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_serveur&lt;/code&gt; pour obtenir une fonction &lt;i&gt;f&lt;/i&gt; qu'elles appliquent sur leurs arguments, y compris le nom du serveur.&lt;br class='autobr' /&gt;
Toutes les fonctions dont le nom est ainsi construit sont r&#233;serv&#233;es &#224; l'interface de SPIP aux serveurs SQL.&lt;/p&gt;
&lt;p&gt;Dans une vision &lt;i&gt;orient&#233;e objet&lt;/i&gt;, ce jeu de fonctions repr&#233;sente les &lt;i&gt;m&#233;thodes&lt;/i&gt; de l'objet &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql&lt;/code&gt;, mais on &#233;crit &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_&lt;/code&gt;&lt;i&gt;f&lt;/i&gt; &#224; la place de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql-&gt;&lt;/code&gt;&lt;i&gt;f&lt;/i&gt;, et il n'est pas n&#233;cessaire d'&lt;i&gt;instancier une classe&lt;/i&gt;. La pr&#233;sence du nom du serveur dans tous les appels permet de simuler les op&#233;rations impliquant l'objet &lt;i&gt;moi-m&#234;me&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Ce jeu de fonctions dispense donc la plupart du temps d'utiliser &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_serveur&lt;/code&gt;. Signalons &#233;galement la fonction (pr&#233;sente dans SPIP de longue date) :&lt;/p&gt;
&lt;p&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect($serveur='')&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;qui simplement ouvre la connexion au serveur, et est donc &#233;quivalente &#224;&lt;/p&gt;
&lt;p&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_serveur('', $serveur, true)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;et qui retourne &lt;i&gt;false&lt;/i&gt; si le serveur est indisponible, sinon la structure de donn&#233;es d&#233;crivant les possibilit&#233;s du serveur.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Fonctions-disponibles&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Fonctions-disponibles'&gt;Fonctions disponibles&lt;a class='sommaire-back sommaire-back-3' href='#s-Fonctions-disponibles' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les fonctions de l'interface SQL peuvent se classer en plusieurs groupes, pour lesquels on donnera &#224; chaque fois un tableau pr&#233;sentant leurs arguments. Pour les exemples on se reportera au code de SPIP.&lt;/p&gt;
&lt;p&gt;Un premier groupe de fonctions concernent la lecture des tables SQL.&lt;br class='autobr' /&gt;
Les fonctions incontournables sont :&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt; dont les arguments sont les clauses SQL habituelles de cette instruction, et dont le r&#233;sultat est une &lt;i&gt;ressource Select&lt;/i&gt; ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetch&lt;/code&gt;, utilis&#233;e presque toujours dans une boucle, qui permet de r&#233;cup&#233;rer les lignes successives d'une ressource Select ; son r&#233;sultat est un tableau index&#233; par le nom des champs ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_free&lt;/code&gt; qui signale au serveur de lib&#233;rer une ressource.&lt;/p&gt;
&lt;p&gt;D'autres fonctions offrent des compositions fr&#233;quentes de ces op&#233;rations :&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetsel&lt;/code&gt; de m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt;, qui applique celle-ci sur ses arguments puis &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetch&lt;/code&gt; sur la ressource retourn&#233;e ; pratique pour les requ&#234;tes dont le r&#233;sultat ne comporte qu'une ligne ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_getfetsel&lt;/code&gt; de m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt;, qui applique celle-ci sur ses arguments puis &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetch&lt;/code&gt; sur la ressource retourn&#233;e, et enfin extrait du tableau retourn&#233; le champ dont le nom est donn&#233; comme premier argument (la liste des champs n'en comporte donc qu'un) ; pratique pour les requ&#234;tes dont le r&#233;sultat ne comporte qu'une ligne d'un seul champ ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_allfetsel&lt;/code&gt; de m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt;, qui applique celle-ci sur ses arguments puis &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetch&lt;/code&gt; sur la ressource retourn&#233;e tant que celui-ci retourne un tableau non vide ; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_allfetsel&lt;/code&gt; retourne pour finir le tableau de tous les tableaux retourn&#233;s par &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_fetch&lt;/code&gt; (attention &#224; ne pas saturer la m&#233;moire avec cette fonction) ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_countsel&lt;/code&gt; de m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt; moins le premier, qui applique celle-ci sur &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;COUNT(*)&lt;/code&gt; et ses autres arguments et retourne le nombre calcul&#233; ; pratique pour conna&#238;tre le nombre de lignes que retournerait la requ&#234;te Select ainsi d&#233;crite.&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_count&lt;/code&gt; qui retourne le nombre de lignes d'une ressource Select, comme si on avait ajout&#233; &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;COUNT(*)&lt;/code&gt; dans la requ&#234;te ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_get_select&lt;/code&gt; utilise les m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_select&lt;/code&gt;, mais retourne le code SQL de la requ&#234;te, sans l'ex&#233;cuter. Cette fonction peut-&#234;tre utile pour les besoins de certains plugins ou pour cr&#233;er facilement des vues SQL.&lt;/p&gt;
&lt;p&gt;Les quatre premi&#232;res appellent pour finir &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_free&lt;/code&gt;, et sont donc &#224; pr&#233;f&#233;rer autant que possible au trio &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;select-fetch-free&lt;/code&gt; dont on oublie facilement le dernier membre.&lt;/p&gt;
&lt;p&gt;Le tableau ci-dessous pr&#233;cise le contenu et l'ordre des arguments attendus par ces fonctions.&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_select&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;liste des champs : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_fetch&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;ressource&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_free&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;ressource&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_count&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;ressource&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_countsel&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_fetsel&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;liste des champs : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_allfetsel&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;liste des champs : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_getfetsel&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom d'un champ : cha&#238;ne&lt;/li&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_get_select&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;liste des champs : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;liste des tables : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Where : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt; clause Groupby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Orderby : cha&#238;ne avec virgule s&#233;paratrice ou tableau&lt;/li&gt;&lt;li&gt; clause Limit : un ou deux entiers s&#233;par&#233;s par des virgules&lt;/li&gt;&lt;li&gt;clause Having : cha&#238;ne ou tableau&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Dans les fonctions ci-dessus, si la clause Select est fournie sous forme de tableau, ses &#233;l&#233;ments seront concat&#233;n&#233;s, s&#233;par&#233;s par des virgules.&lt;br class='autobr' /&gt;
En cas de tableau pour les clauses Where et Having, les &#233;l&#233;ments doivent &#234;tre des cha&#238;nes (des sous-tableaux en notation pr&#233;fix&#233;e sont &#233;galement pris en charge, mais r&#233;serv&#233;s au compilateur). Ces cha&#238;nes seront r&#233;unies en une grande conjonction (i.e, elles seront concat&#233;n&#233;es avec AND comme s&#233;parateur).&lt;/p&gt;
&lt;p&gt;La clause From est une cha&#238;ne (le cas du tableau est r&#233;serv&#233; au compilateur de SPIP).&lt;br class='autobr' /&gt;
Attention : s'il est n&#233;cessaire de r&#233;f&#233;rencer les tables dans les autres clauses, il faut en d&#233;finir des alias dans ce param&#232;tre et les utiliser syst&#233;matiquement. Ainsi, on &#233;crira :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_countsel('spip_articles AS a, spip_rubriques AS r', &#034;a.id_secteur=r.id_rubrique AND r.titre='monsecteur') &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;ou&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_countsel('spip_articles AS a JOIN spip_rubriques AS r ON a.id_secteur=r.id_rubrique&#034;, &#034;r.titre='monsecteur'&#034;) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;alors que l'&#233;criture suivante ne sera pas comprise :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;sql_countsel('spip_articles, spip_rubriques', &#034;spip_articles.id_rubrique=spip_rubriques.id_secteur AND spip_rubriques.titre='monsecteur'&#034;) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Un deuxi&#232;me groupe de fonctions est constitu&#233; par celles modifiant le contenu des tables. Ces fonctions sont d&#233;licates &#224; d&#233;finir car la syntaxe des valeurs &#224; introduire dans les tables change d'un serveur SQL &#224; un autre (notamment les dates). Pour cette raison, ces fonctions doivent disposer de la description de la table &#224; modifier, afin de conna&#238;tre le type des valeurs attendues par le serveur SQL. SPIP retrouve automatiquement ces informations (donn&#233;es au moment de la cr&#233;ation de la table) mais il est possible de fournir une description arbitraire (avant-dernier argument de ces fonctions, optionnel et d'ailleurs rarement utile).&lt;/p&gt;
&lt;p&gt;SPIP fournit donc une fonction d'insertion, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_insertq&lt;/code&gt;, et une fonction de mise &#224; jour, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_updateq&lt;/code&gt;, qui prennent un tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur&lt;/i&gt; et s'occupent de &lt;i&gt;citer&lt;/i&gt; les valeurs en fonction du type (avec la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_quote&lt;/code&gt; sp&#233;cifi&#233;e ci-dessous).&lt;/p&gt;
&lt;p&gt;Est &#233;galement disponible &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_insertq_multi&lt;/code&gt; permettant de faire des insertions de plusieurs entr&#233;es en prenant un tableau de tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Pour les mises &#224; jour o&#249; les nouvelles valeurs d&#233;pendent des anciennes (comme dans &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;cpt=cpt+1&lt;/code&gt;), utiliser &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_update&lt;/code&gt; o&#249; les valeurs seront prises litt&#233;rallement, mais il faudra interdire soigneusement les possibilit&#233;s d'attaque par injection de code.&lt;/p&gt;
&lt;p&gt;Il existe &#233;galement &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_replace&lt;/code&gt;, fonction effectuant une mise &#224; jour sur une ligne correspondant &#224; une cl&#233; primaire, ou ins&#233;rant les valeurs si cette ligne n'existe pas &lt;br class='autobr' /&gt;
ainsi qu'une fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_replace_multi&lt;/code&gt; pour des mises &#224; jour ou insertions multiples.&lt;br class='autobr' /&gt;
Enfin, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_delete&lt;/code&gt; efface d'une table les lignes r&#233;pondant &#224; une clause Where.&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_updateq&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur &#224; citer&lt;/i&gt;&lt;/li&gt;&lt;li&gt; clause Where&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_update&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur&lt;/i&gt;&lt;/li&gt;&lt;li&gt; clause Where&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_insertq&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur &#224; citer&lt;/i&gt;&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_insertq_multi&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau de tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur &#224; citer&lt;/i&gt;&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_replace&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur &#224; citer&lt;/i&gt;&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_replace_multi&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;tableau de tableau &lt;i&gt;champ&lt;/i&gt;=&gt;&lt;i&gt;valeur &#224; citer&lt;/i&gt;&lt;/li&gt;&lt;li&gt; description&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_delete&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt; clause Where&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Un groupe un peu &#224; part est form&#233; de fonctions traitant sp&#233;cifiquement des op&#233;randes. : elles ne se connectent pas au serveur, mais retournent des cha&#238;nes d&#233;pendant de celui-ci :&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_quote&lt;/code&gt; prend une cha&#238;ne ou un nombre, retourne un nombre si l'argument &#233;tait un nombre ou une cha&#238;ne repr&#233;sentant un entier, sinon retourne la cha&#238;ne initiale entour&#233;e d'apostrophes et avec les apostrophes prot&#233;g&#233;es selon la syntaxe propre au serveur (un \ devant pour certains, une deuxi&#232;me apostrophe pour d'autres) ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_hex&lt;/code&gt; prend une cha&#238;ne de chiffres hexad&#233;cimaux et retourne sa repr&#233;sentation dans le serveur SQL vis&#233; ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_in&lt;/code&gt; construit un appel &#224; l'op&#233;rande IN, en traitant les &#233;ventuelles valeurs hexad&#233;cimales y figurant ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_test_int&lt;/code&gt; pr&#233;dicat retournant Vrai si le type SQL fourni d&#233;signe un entier ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_test_date&lt;/code&gt; pr&#233;dicat retournant Vrai si le type SQL fourni d&#233;signe une date ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_multi&lt;/code&gt; applique une expression SQL sur champ contenant un &lt;i&gt;bloc multi&lt;/i&gt; (voir &lt;a href='https://www.spip.net/fr_article2124.html' class=&#034;spip_in&#034;&gt;R&#233;aliser un site multilingue&lt;/a&gt;) pour y prendre la partie correspondant &#224; la langue indiqu&#233;e ; l'int&#233;r&#234;t d'effectuer cette op&#233;ration au niveau SQL est essentiellement de demander simultan&#233;ment un tri sur cette colonne.&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_quote&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;valeur&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_hex&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;valeur&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_in&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;colonne&lt;/li&gt;&lt;li&gt; valeurs&lt;/li&gt;&lt;li&gt; vrai si n&#233;gation souhait&#233;e&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_multi&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;colonne&lt;/li&gt;&lt;li&gt; langue&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_test_date&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;type&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_test_int&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;type&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Un groupe important est constitu&#233; par les fonctions manipulant les d&#233;clarations de bases et de tables. Pour des raisons historiques, cette premi&#232;re version de l'interface reprend quasi litt&#233;ralement la syntaxe de MySQL3 et devra certainement &#234;tre revue, en particulier pour y faire appara&#238;tre la d&#233;claration des jointures. Les fonctions &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_create&lt;/code&gt;, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_alter&lt;/code&gt;, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_showtable&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_drop_table&lt;/code&gt; permettent de cr&#233;er, modifier, voir et supprimer une table.&lt;/p&gt;
&lt;p&gt;Les fonctions &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_create_view&lt;/code&gt;, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_drop_view&lt;/code&gt; permettent de cr&#233;er ou supprimer une vue.&lt;/p&gt;
&lt;p&gt; Les fonctions &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_listdbs&lt;/code&gt;, &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_showbase&lt;/code&gt; et &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_selectdb&lt;/code&gt; permettent de voir les bases accessibles, de voir leur contenu et d'en s&#233;lectionner une. &#192; noter que tous les h&#233;bergeurs n'autorisent pas forc&#233;ment de telles actions ; SPIP essaiera de le deviner, en notant ses essais dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip.log&lt;/code&gt;.&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_create&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom de la table&lt;/li&gt;&lt;li&gt; tableau nom de colonne =&gt; type SQL et valeur par d&#233;faut&lt;/li&gt;&lt;li&gt; tableau nom d'index =&gt; colonne(s)&lt;/li&gt;&lt;li&gt; vrai si auto-incr&#233;ment&lt;/li&gt;&lt;li&gt; vrai si temporaire&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_alter&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;requ&#234;te MYSQL Alter&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_showtable&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;RegExp&lt;/li&gt;&lt;li&gt; vrai si table d&#233;clar&#233;e par SPIP&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_drop_table&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom de la table&lt;/li&gt;&lt;li&gt; vrai s'il faut ins&#233;rer la condition &lt;i&gt;existe&lt;/i&gt;&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_create_view&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom de la vue&lt;/li&gt;&lt;li&gt;requ&#234;te de s&#233;lection de champs (cr&#233;&#233; par exemple avec &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_get_select&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_drop_view&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom de la vue&lt;/li&gt;&lt;li&gt; vrai s'il faut ins&#233;rer la condition &lt;i&gt;existe&lt;/i&gt;&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_listdbs&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_selectdb&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;nom de la base&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_showbase&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;RegExp&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Deux fonctions permettent de r&#233;gler le codage des caract&#232;res lors des communications avec le serveur :&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_set_charset&lt;/code&gt;, demande d'utiliser le codage indiqu&#233; ;&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_get_charset&lt;/code&gt;, demande si un codage de nom donn&#233; est disponible sur le serveur.&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_get_charset&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;RegExp&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_set_charset&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;codage&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Un dernier groupe de fonctions offre quelques outils de gestion des requ&#234;tes et des tables ; on se reportera &#224; leurs homonymes dans la documentation des serveurs SQL.&lt;/p&gt;
&lt;p&gt;Signalons toutefois que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_explain&lt;/code&gt; est utilis&#233;e implicitement par le d&#233;busqueur de SPIP, accessible par les boutons d'administration de l'espace public, lorsqu'on lui demande le plan de calcul d'une boucle (ou de tout un squelette).&lt;/p&gt;
&lt;table class=&#034;table spip&#034;&gt;
&lt;tbody&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;Fonction&lt;/td&gt;
&lt;td&gt;Arguments&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_optimize&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;requ&#234;te&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_repair&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;table&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_explain&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;requ&#234;te&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_error&lt;/td&gt;
&lt;td&gt;&lt;ol&gt;&lt;li&gt;requ&#234;te&lt;/li&gt;&lt;li&gt;serveur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_even even'&gt;
&lt;td&gt;sql_errno&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr class='row_odd odd'&gt;
&lt;td&gt;sql_version&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Hors groupe, la fonction g&#233;n&#233;rale &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;sql_query&lt;/code&gt;, nom qu'aurait d&#251; porter l'historique &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_query&lt;/code&gt; ; leur utilisation est de toute fa&#231;on &#224; &#233;viter.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Realisation-des-portages&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Realisation-des-portages'&gt;R&#233;alisation des portages&lt;a class='sommaire-back sommaire-back-3' href='#s-Realisation-des-portages' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Cette section est destin&#233;e &#224; ceux souhaitant porter SPIP sur d'autres serveurs SQL, ou ayant besoin d'informations plus techniques, notamment sur la gestion des versions de l'interface. &lt;br class='autobr' /&gt;
Les fonctions du fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;ecrire/base/abstract_sql.php&lt;/code&gt; &#233;tudi&#233;es ci-dessus se contentent d'offrir une interface homog&#232;ne aux diff&#233;rents serveurs, mais ne proc&#232;dent elles-m&#234;mes &#224; aucun calcul. &lt;br class='autobr' /&gt;
C'est dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;ecrire/base/connect_sql.php&lt;/code&gt; que se situe le travail effectif.&lt;/p&gt;
&lt;p&gt;La fonction essentielle est &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect&lt;/code&gt; qui ouvre la connexion au serveur SQL indiqu&#233; par son argument (ou, s'il est omis, le serveur principal) en rep&#233;rant les connexions d&#233;j&#224; faites. Cette ouverture consiste &#224; inclure un &lt;i&gt;fichier de connexion&lt;/i&gt; cr&#233;&#233; lors de l'installation de SPIP par les scripts pr&#233;sents dans le r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;install&lt;/code&gt;. Un fichier de connexion se r&#233;duit pour l'essentiel &#224; appliquer la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect_db&lt;/code&gt; aux valeurs fournies lors de l'installation.&lt;/p&gt;
&lt;p&gt;La fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect_db&lt;/code&gt; re&#231;oit en particulier comme argument le type du serveur SQL. Ce type doit &#234;tre le nom d'un fichier pr&#233;sent dans le r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;req&lt;/code&gt;.&lt;br class='autobr' /&gt;
Ce fichier est charg&#233; et doit d&#233;finir toutes les fonctions d'interfaces d&#233;finies &#224; la section pr&#233;c&#233;dente, plus la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;req_&lt;/code&gt;&lt;i&gt;type&lt;/i&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;_dist&lt;/code&gt; qui sera imm&#233;diatement appliqu&#233;e sur les m&#234;mes arguments que &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect_db&lt;/code&gt;, type except&#233;. C'est cette fonction qui doit &#233;tablir effectivement la connexion.&lt;/p&gt;
&lt;p&gt;Porter SPIP sur d'autres serveurs SQL consiste donc &#224; d&#233;finir ce jeu de fonctions et &#224; le placer dans le r&#233;pertoire &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;req&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le gestionnaire de versions d'interface repose sur le deuxi&#232;me argument de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect&lt;/code&gt; qui indique la version, la version courante &#233;tant prise par d&#233;faut.&lt;br class='autobr' /&gt;
Toutes les fonctions de l'interface sont d&#233;finies dans le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;abstract_sql&lt;/code&gt;, se nomment sql_&lt;i&gt;X&lt;/i&gt; et sont les seules &#224; se nommer ainsi. &lt;br class='autobr' /&gt;
Elles se connectent toutes en appelant une variante de &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_connect&lt;/code&gt; dont le premier argument est le num&#233;ro de version de l'interface. Au cas o&#249; le fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;abstract_sql&lt;/code&gt; n&#233;cessiterait une r&#233;vision, il sera renomm&#233; abstract_sql_&lt;i&gt;N&lt;/i&gt;, et le Sed suivant lui sera appliqu&#233; (&lt;i&gt;N&lt;/i&gt; d&#233;signe le num&#233;ro de version) :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre class='spip_code spip_code_block' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;s/\(sql_[A-Za-z_0-9 ]*\)/\1_N/ &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;En appliquant &#233;galement ce script aux extensions de SPIP fond&#233;es sur cette version, on leur permettra d'en appeler ses fonctions, qui seront charg&#233;es sans collision de noms, le Sed ayant pr&#233;fix&#233; le nom des anciennes avec leur num&#233;ro de version. Il faudra juste rajouter une instruction include portant sur le fichier abstract_sql_&lt;i&gt;N&lt;/i&gt;. &lt;br class='autobr' /&gt;
Du c&#244;t&#233; du portage, il faudra renommer pareillement les fichiers du r&#233;pertoire &lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;req&lt;/code&gt;, et &#233;crire les nouvelles versions.&lt;/p&gt;
&lt;p&gt;La coexistence de plusieurs versions de l'interface pendant l'ex&#233;cution de SPIP repose sur la structure d&#233;crivant le serveur. Celle-ci est en fait un tableau, contenant :&lt;/p&gt;
&lt;p&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;link&lt;/code&gt;, &lt;i&gt;ressource&lt;/i&gt; indiquant la connexion ;
&lt;br /&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;db&lt;/code&gt;, nom de la base de donn&#233;es ;
&lt;br /&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;prefixe&lt;/code&gt;, nom du pr&#233;fixe de table ;
&lt;br /&gt;- &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;ldap&lt;/code&gt;, nom de l'&#233;ventuel fichier d&#233;crivant le serveur LDAP.&lt;/p&gt;
&lt;p&gt;Les autres entr&#233;es sont les num&#233;ros de versions disponibles, et leur valeur est le tableau des fonctions impl&#233;mentant cette version de l'interface.&lt;/p&gt;
&lt;p&gt;Les autres fonctions du fichier &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;connect_sql&lt;/code&gt;concernent essentiellement la gestion des versions et le traitement de quelques cas particuliers de d&#233;clarations des tables standards de SPIP.&lt;/p&gt;&lt;/section&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>
<item xml:lang="fr">
		<title>Mutualisation du noyau SPIP</title>
		<link>https://www.spip.net/fr_article3514.html</link>
		<guid isPermaLink="true">https://www.spip.net/fr_article3514.html</guid>
		<dc:date>2007-02-22T21:04:45Z</dc:date>
		<dc:format>text/html</dc:format>
		<dc:language>fr</dc:language>
		<dc:creator>Committo, Ergo Sum., Matthieu Marcillaud</dc:creator>



		<description>&lt;p&gt;Proc&#233;dure pour partager le noyau de SPIP entre plusieurs sites.&lt;/p&gt;

-
&lt;a href="https://www.spip.net/fr_rubrique468.html" rel="directory"&gt;Optimisation / Syst&#232;me&lt;/a&gt;


		</description>


 <content:encoded>&lt;div class='rss_chapo'&gt;&lt;p&gt;La mutualisation du noyau de SPIP est possible. Il s'agit de pouvoir g&#233;rer plusieurs sites SPIP sur un seul serveur ou h&#233;bergement en n'utilisant qu'une seule fois les fichiers du noyau de SPIP.&lt;/p&gt;
&lt;p&gt;Cela permet un gain d'espace disque important, ainsi qu'une possibilit&#233; de mise &#224; jour de SPIP simple de l'ensemble des sites en ne mettant &#224; jour que le noyau.&lt;/p&gt;&lt;/div&gt;
		&lt;div class='rss_texte'&gt;&lt;!--sommaire--&gt;&lt;div class=&#034;well nav-sommaire nav-sommaire-6&#034; id=&#034;nav6a10dbd32e0af7.60240858&#034;&gt;
&lt;h2&gt;Sommaire&lt;/h2&gt;&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; &lt;a id=&#034;s-Le-concept&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Le-concept&#034; class=&#034;spip_ancre&#034;&gt;Le concept...&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Creer-les-bons-repertoires&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Creer-les-bons-repertoires&#034; class=&#034;spip_ancre&#034;&gt;Cr&#233;er les bons r&#233;pertoires&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Des-redirections-bien-faites&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Des-redirections-bien-faites&#034; class=&#034;spip_ancre&#034;&gt;Des redirections bien faites !&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Mutualiser-selon-l-URL-grace-a-mes_options-php&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Mutualiser-selon-l-URL-grace-a-mes_options-php&#034; class=&#034;spip_ancre&#034;&gt;Mutualiser selon l'URL gr&#226;ce &#224; mes_options.php&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Configurer-apache-pour-les-domaines-et-sous-domaines&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Configurer-apache-pour-les-domaines-et-sous-domaines&#034; class=&#034;spip_ancre&#034;&gt;Configurer apache pour les domaines et sous-domaines&lt;/a&gt;&lt;/li&gt;&lt;li&gt; &lt;a id=&#034;s-Note-sur-les-sauvegardes-et-les-restaurations&#034;&gt;&lt;/a&gt;&lt;a href=&#034;#Note-sur-les-sauvegardes-et-les-restaurations&#034; class=&#034;spip_ancre&#034;&gt;Note sur les sauvegardes et les restaurations&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;!--/sommaire--&gt;&lt;p&gt;Cet article explique la proc&#233;dure pour &lt;a href='https://www.spip.net/fr_article3567.html' class=&#034;spip_in&#034;&gt;SPIP 1.9.2&lt;/a&gt;, sur des serveurs Apache&lt;span class=&#034;spip_note_ref&#034;&gt; [&lt;a href=&#034;#nb1&#034; class=&#034;spip_note&#034; rel=&#034;appendix&#034; title=&#034;Pour information : ces proc&#233;dures ont &#233;t&#233; test&#233;es avec Apache 2.0.55 et PHP (&#8230;)&#034; id=&#034;nh1&#034;&gt;1&lt;/a&gt;]&lt;/span&gt; autorisant la r&#233;&#233;criture d'url (url_rewriting). Pour les versions ult&#233;rieures de SPIP, voir plut&#244;t l'article &lt;a href=&#034;http://www.spip-contrib.net/Ferme-a-SPIP&#034; class=&#034;spip_out&#034; rel=&#034;external&#034;&gt;Ferme &#224; SPIP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il y a plusieurs m&#233;thodes pour arriver aux m&#234;mes r&#233;sultats, selon que l'on souhaite configurer directement la mutualisation depuis un h&#233;bergement ou depuis un serveur.&lt;/p&gt;
&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Le-concept&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Le-concept'&gt;Le concept...&lt;a class='sommaire-back sommaire-back-6' href='#s-Le-concept' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les dossiers n&#233;cessaires au fonctionnement du noyau SPIP (ecrire, plugins-dist, prive, squelettes-dist, ...), et ceux marquant l'activit&#233; d'un site (config, IMG, tmp, local) sont clairement identifiables et s&#233;par&#233;s. C'est cette s&#233;paration qui permet d'avoir plusieurs sites SPIP autonomes pour un m&#234;me noyau de SPIP.&lt;/p&gt;
&lt;p&gt;Cette autonomie repose sur l'existence d'un quatuor de r&#233;pertoires par site, dans lesquels Spip va &#233;crire les donn&#233;es r&#233;sultant de l'activit&#233; du site. Ces r&#233;pertoires sont au nombre de quatre, car on distingue les donn&#233;es temporaires et permanentes d'une part, et les donn&#233;es accessibles par http et celles qui ne le sont pas d'autre part, d'o&#249; quatre types de donn&#233;es. Les deux r&#233;pertoires inaccessibles par http seront prot&#233;g&#233;es par un .htaccess install&#233; automatiquement par SPIP (les administrateurs du serveur pourront m&#234;me mettre ces r&#233;pertoires en dehors de l'arborescence servie par http).&lt;/p&gt;
&lt;p&gt;Ces quatre r&#233;pertoires sont distincts et nomm&#233;s par les constantes PHP suivantes :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;define('_NOM_TEMPORAIRES_INACCESSIBLES', &#034;tmp/&#034;); define('_NOM_TEMPORAIRES_ACCESSIBLES', &#034;local/&#034;); define('_NOM_PERMANENTS_INACCESSIBLES', &#034;config/&#034;); define('_NOM_PERMANENTS_ACCESSIBLES', &#034;IMG/&#034;); &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dans une installation de Spip non mutualis&#233;e, ces r&#233;pertoires sont cr&#233;&#233;s &#224; la racine du site, lors de l'application de la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_initialisation&lt;/code&gt; sur les quatre valeurs ci-dessus. Pour obtenir la mutualisation des sources de SPIP,&lt;br class='autobr' /&gt;
il suffit de savoir associer une URL sp&#233;cifique &#224; son quatuor de r&#233;pertoires sp&#233;cifiques, en appelant la fonction &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;spip_initialisation&lt;/code&gt; sur quatre autres valeurs, d&#233;duites de l'URL.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Creer-les-bons-repertoires&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Creer-les-bons-repertoires'&gt;Cr&#233;er les bons r&#233;pertoires&lt;a class='sommaire-back sommaire-back-6' href='#s-Creer-les-bons-repertoires' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour d&#233;marrer la mutualisation, il faut tout d'abord partir d'un site fonctionnel. Pour les exemples, nous partirons d'un site appel&#233; par l'url &lt;a href=&#034;http://example.org/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/&lt;/a&gt; stock&#233; physiquement dans /home/toto/public_html/.&lt;/p&gt;
&lt;p&gt;Il faut cr&#233;er un r&#233;pertoire (par exemple nomm&#233; 'sites') qui va contenir les r&#233;pertoires des sites mutualis&#233;s, &#224; la racine de la distribution (au m&#234;me niveau que /ecrire).&lt;/p&gt;
&lt;p&gt;- mutualisation d'un r&#233;pertoire :&lt;br class='autobr' /&gt;
Si l'on souhaite que les adresses &lt;a href=&#034;http://example.org/premier_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site/&lt;/a&gt; et &lt;a href=&#034;http://example.org/deuxieme_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/deuxieme_site/&lt;/a&gt; appellent chacun un site spip, il faut cr&#233;er alors les sous-r&#233;pertoires /premier_site et /deuxieme_site dans le r&#233;pertoire /sites, puis dans chacun d'eux cr&#233;er les r&#233;pertoires /config, /IMG, /tmp, /local. Ces quatre r&#233;pertoires doivent &#234;tre accessibles en &#233;criture. Il sera possible par la suite d'ajouter un r&#233;pertoire /squelettes aussi, &#224; c&#244;t&#233; de ces r&#233;pertoires.&lt;/p&gt;
&lt;p&gt;- mutualisation sous-domaine et domaine (quelques id&#233;es) :&lt;br class='autobr' /&gt;
Si l'on souhaite que l'adresse &lt;a href=&#034;http://toto.example.org/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://toto.example.org/&lt;/a&gt;, &lt;a href=&#034;http://exemple.tld/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://exemple.tld/&lt;/a&gt; et &lt;a href=&#034;http://utilisateur.example.com/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://utilisateur.example.com/&lt;/a&gt; appellent chacun un site spip, on peut envisager de cr&#233;er dans /sites les r&#233;pertoires /toto, /exemple.tld, et /example.com/utilisateur&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remarque :&lt;/strong&gt; Toutes les url doivent pointer &#224; la racine de la distribution SPIP, c'est-&#224;-dire dans /home/toto/public_html/. C'est le r&#244;le que vont remplir soit un fichier .htaccess soit la configuration du serveur Apache expliqu&#233;s plus loin.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Des-redirections-bien-faites&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Des-redirections-bien-faites'&gt;Des redirections bien faites !&lt;a class='sommaire-back sommaire-back-6' href='#s-Des-redirections-bien-faites' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour que SPIP reconnaisse qu'un site est mutualis&#233;, il faut que le script spip.php (appel&#233; par index.php) soit execut&#233;. Celui-ci cherchera, gr&#226;ce &#224; un code ajout&#233; dans /config/mes_options.php si l'URL appel&#233;e correspond &#224; un site mutualis&#233; ou non. Pour cela, il faut qu'une adresse &lt;a href=&#034;http://example.org/premier_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site/&lt;/a&gt; ou &lt;a href=&#034;http://example.org/deuxieme_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/deuxieme_site/&lt;/a&gt; soit redirig&#233;e vers &lt;a href=&#034;http://example.org/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/&lt;/a&gt; pour executer alors index.php...&lt;/p&gt;
&lt;p&gt;C'est le r&#244;le attribu&#233; au fichier .htaccess (ou directement dans la configuration du serveur Apache)&lt;/p&gt;
&lt;p&gt;Il faut copier et renommer le fichier htaccess.txt &#224; la racine de la distribution en .htaccess, puis le modifier :&lt;/p&gt;
&lt;p&gt;Pour autoriser la r&#233;&#233;criture d'URL (rien ne change normalement) :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;RewriteEngine On&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Si la distribution SPIP est dans un sous-r&#233;pertoire, modifier rewritebase. Ici, le site est &#224; la racine donc :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;RewriteBase /&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Enfin, dans r&#233;glages personnalis&#233;s, ajouter le code suivant pour que les r&#233;pertoires /premier_site , /deuxieme_site et /troisieme_site soient trait&#233;s depuis la racine de la distribution :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;#Mutualisation RewriteRule ^(premier_site|deuxieme_site|troisieme_site)$ /$1/ [R,L] RewriteRule ^(premier_site|deuxieme_site|troisieme_site)/(.*) /$2 [QSA,L]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Le premier rewriterule redirige les adresses &lt;a href=&#034;http://example.org/premier_site&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site&lt;/a&gt; vers &lt;a href=&#034;http://example.org/premier_site{{/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site{{/&lt;/a&gt;&lt;/strong&gt;. Le deuxi&#232;me redirige tout ce qu'il y a derri&#232;re /premier_site/ &#224; la racine, par exemple : &lt;a href=&#034;http://example.org/premier_site/article112&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site/article112&lt;/a&gt; est redirig&#233; vers &lt;a href=&#034;http://example.org/article112&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/article112&lt;/a&gt;. (Cependant, cette redirection est transparente, le nom de l'url ne change pas, il est toujours &lt;a href=&#034;http://example.org/premier_site/article112&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site/article112&lt;/a&gt;, m&#234;me et surtout pour php !)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Et si SPIP est dans un sous r&#233;pertoire ?&lt;/strong&gt;&lt;br class='manualbr' /&gt;Dans ce cas l&#224;, les fichiers de spip se trouvent dans /home/toto/public_html/spip/ , SPIP est appel&#233; par &lt;a href=&#034;http://example.org/spip/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/spip/&lt;/a&gt;, les sites mutualis&#233;s par &lt;a href=&#034;http://example.org/spip/premier_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/spip/premier_site/&lt;/a&gt; ou &lt;a href=&#034;http://example.org/spip/deuxieme_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/spip/deuxieme_site/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Il faut alors mettre dans le .htaccess :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;RewriteEngine On RewriteBase /spip/ #Mutualisation RewriteRule ^(premier_site|deuxieme_site|troisieme_site)$ /spip/$1/ [R,L] RewriteRule ^(premier_site|deuxieme_site|troisieme_site)/(.*) /spip/$2 [QSA,L] &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Et pour rediriger tous les r&#233;pertoires comme des sites mutualis&#233;s ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Il vous est possible &lt;strong&gt;&#224; la place&lt;/strong&gt; des rewriterules ci-dessus &lt;br class='autobr' /&gt;
d'utiliser un code g&#233;n&#233;rique, utilisable quelque-soit le nom du &lt;br class='autobr' /&gt;
r&#233;pertoire du site mutualis&#233; :&lt;/p&gt;
&lt;p&gt;- &#224; la racine&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;RewriteCond %{REQUEST_URI} !^/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*) RewriteRule ^[^/]+/(.*) /$1 [QSA,L] &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;- ou dans un dossier /spip :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;RewriteCond %{REQUEST_URI} !^/spip/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*) RewriteRule ^[^/]+/(.*) /spip/$1 [QSA,L] &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Et pour les domaines et sous domaines ?&lt;/strong&gt;&lt;br class='manualbr' /&gt;Par un heureux hasard, il n'y a rien &#224; faire ici puisqu'ils pointent normalement d&#233;j&#224; vers la racine de la distribution SPIP...&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Mutualiser-selon-l-URL-grace-a-mes_options-php&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Mutualiser-selon-l-URL-grace-a-mes_options-php'&gt;Mutualiser selon l'URL gr&#226;ce &#224; mes_options.php&lt;a class='sommaire-back sommaire-back-6' href='#s-Mutualiser-selon-l-URL-grace-a-mes_options-php' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;C'est le fichier /config/mes_options.php &#224; la racine de la distribution qui va r&#233;aliser la majeure partie du travail : il doit chercher si une URL est &#224; mutualiser ou non, et initialiser SPIP en fonction.&lt;/p&gt;
&lt;p&gt;De nombreux cas peuvent se pr&#233;senter, entre les r&#233;pertoires, les domaines et sous domaines. PHP peut utiliser deux variables pour tester les URLs qui ont appel&#233; le script : &lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$_SERVER['REQUEST_URI']; // contient tout ce qu'il y a derri&#232;re le nom de domaine : /premier_site/article112 par exemple... $_SERVER['SERVER_NAME']; // contient le nom du domaine et sous domaine : utilisateur.example.org par exemple&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ce sont ces deux variables qui vont &#234;tre compar&#233;es &#224; une expression r&#233;guli&#232;re pour extraire le nom du r&#233;pertoire qui contient la mutualisation.&lt;/p&gt;
&lt;p&gt;Un moyen simple de mutualiser tous les r&#233;pertoires est de copier le code suivant :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;&lt;?php if ( preg_match(',/([a-zA-Z0-9_-]+)/?,',$_SERVER['REQUEST_URI'],$r)) { if (is_dir($e = _DIR_RACINE . 'sites/' . $r[1]. '/')) { $cookie_prefix = $table_prefix = $r[1]; define('_SPIP_PATH', $e . ':' . _DIR_RACINE .':' . _DIR_RACINE .'squelettes-dist/:' . _DIR_RACINE.'prive/:'. _DIR_RESTREINT); spip_initialisation( ($e . _NOM_PERMANENTS_INACCESSIBLES), ($e . _NOM_PERMANENTS_ACCESSIBLES), ($e . _NOM_TEMPORAIRES_INACCESSIBLES), ($e . _NOM_TEMPORAIRES_ACCESSIBLES) ); $GLOBALS['dossier_squelettes'] = $e.'squelettes'; if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f); } } ?&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La ligne preg_match r&#233;cup&#232;re le nom d'un dossier dans l'arborescence de l'URL, par exemple 'premier_site' dans &lt;a href=&#034;http://example.org/premier_site/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://example.org/premier_site/&lt;/a&gt; ... Puis le script tente une mutualisation si le r&#233;pertoire /sites/premier_site/ existe.&lt;/p&gt;
&lt;p&gt;Si SPIP est dans un r&#233;pertoire /spip, il faut modifier la premi&#232;re ligne par :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;if (preg_match(',/spip/([a-zA-Z0-9_-]+)/?,', $_SERVER['REQUEST_URI'], $r)) {&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Il faut dire dire &#224; SPIP quel est le pr&#233;fixe de table de base de donn&#233;es utilis&#233;, ce que fait &lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$cookie_prefix = $table_prefix = $r[1];&lt;/code&gt;&lt;br class='autobr' /&gt;
Cette ligne va cr&#233;er des tables MySQL avec des pr&#233;fixes ayant le nom du r&#233;pertoire contenant le site : mon_site_article &#224; la place de spip_article par exemple. Cela permet d'h&#233;berger tous les sites sur une seule et m&#234;me base de donn&#233;es. Vous pouvez garder le pr&#233;fixe par d&#233;faut (spip), mais il faut penser &#224; avoir plusieurs bases de donn&#233;es diff&#233;rentes pour chaque site. &lt;br class='autobr' /&gt;
Pour cela, mettre &#224; la place :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre class='spip_code spip_code_block' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;$cookie_prefix = $r[1]; $table_prefix='spip'; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;La fonction spip_initialisation admet quatre param&#232;tres qui sont l'adresse de chacun des r&#233;pertoires n&#233;cessaires au fonctionnement du site mutualis&#233;.&lt;/p&gt;
&lt;p&gt;&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$GLOBALS['dossier_squelettes'] = $e.'squelettes';&lt;/code&gt; d&#233;finit l'emplacement du dossier squelettes du site mutualis&#233;.&lt;/p&gt;
&lt;p&gt;Enfin les derni&#232;res lignes chargent un &#233;ventuel sites/premier_site/config/mes_options.php.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Information :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Toute modification du fichier config/mes_options.php du noyau SPIP affectera les options de tous les sites h&#233;berg&#233;s.&lt;/p&gt;
&lt;p&gt;Par exemple, mettre dans ce fichier :&lt;br class='autobr' /&gt;
&lt;code class='spip_code spip_code_inline' dir='ltr'&gt;$type_urls = 'propres' ;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Donnera par d&#233;faut &#224; tous les sites ce type d'url... Mais chaque site peut le changer dans son propre /sites/mon_site/config/mes_options.php.&lt;/p&gt;
&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Configurer-apache-pour-les-domaines-et-sous-domaines&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Configurer-apache-pour-les-domaines-et-sous-domaines'&gt;Configurer apache pour les domaines et sous-domaines&lt;a class='sommaire-back sommaire-back-6' href='#s-Configurer-apache-pour-les-domaines-et-sous-domaines' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;La mutualisation c&#244;t&#233; serveur, pour ce qui concerne la gestion des sous-domaines ou des domaines reste simple, mais n&#233;cessite de cr&#233;er quelques redirections d'URL dans la configuration du serveur Apache pour tenir compte de ces sites.&lt;/p&gt;
&lt;p&gt;Voici un exemple de configuration pour un serveur nomm&#233; 'exemple.tld' (ici un SPIP mutualis&#233;) utilisant des sous-domaines (SPIP appel&#233; par &lt;a href=&#034;http://utilisateur.example.org/spip/&#034; class=&#034;spip_url spip_out auto&#034; rel=&#034;nofollow external&#034;&gt;http://utilisateur.example.org/spip/&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Le noyau SPIP est dans '/home/toto/public_html/spip/'.&lt;/p&gt;
&lt;p&gt;Il faut alors cr&#233;er les r&#233;pertoires /sites/exemple.tld/ , /sites/exemple.tld/utilisteur/.&lt;/p&gt;
&lt;p&gt;Le fichier de configuration se situe dans Apache 2/linux dans /etc/apache2/sites_availables/default (vous pouvez aussi cr&#233;er un nouveau fichier dans le dossier sites_availables et l'activer).&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;apache&#034; class='spip_code spip_code_block language-apache' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;# SERVEUR exemple.tld # SPIP par sous domaine... &lt;VirtualHost *&gt; ServerName exemple.tld ServerAlias *.exemple.tld # Redirection vers le SPIP noyau DocumentRoot &#034;/home/toto/public_html&#034; &lt;Directory &#034;/home/toto/public_html/&#034;&gt; AllowOverride All Order allow,deny Allow from all &lt;/Directory&gt; # Seule l'adresse http://utilisateur.exemple.tld/spip/* doit &#234;tre redirig&#233;e # (utilisateur.exemple.tld/spip/* -&gt; /home/toto/public_html/*) RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$ RewriteRule ^/spip/(.*) /home/toto/public_html/spip/$1 [QSA,L] # (utilisateur.exemple.tld/* -&gt; /home/toto/public_html/sites/exemple.tld/utilisateur/*) RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$ RewriteRule (.*) /home/toto/public_html/sites/exemple.tld/%1/$1 [QSA,L] &lt;/VirtualHost&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Il est par contre n&#233;cessaire de tester ces mutualisations possibles dans /config/mes_options.php :&lt;/p&gt;
&lt;div class=&#034;precode&#034;&gt;&lt;pre data-language=&#034;php&#034; class='spip_code spip_code_block language-php' dir='ltr' style='text-align:left;'&gt;&lt;code&gt;&lt;?php # pour utilisateur.exemple.tld/spip/ if ( preg_match(',(.*)\.exemple\.tld/spip/?,',$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'],$r)) { if (is_dir($e = _DIR_RACINE . 'sites/exemple.tld/' . $r[1]. '/')) { $cookie_prefix = $table_prefix = $r[1]; define('_SPIP_PATH', $e . ':' . _DIR_RACINE .':' . _DIR_RACINE .'squelettes-dist/:' . _DIR_RACINE.'prive/:'. _DIR_RESTREINT); spip_initialisation( ($e . _NOM_PERMANENTS_INACCESSIBLES), ($e . _NOM_PERMANENTS_ACCESSIBLES), ($e . _NOM_TEMPORAIRES_INACCESSIBLES), ($e . _NOM_TEMPORAIRES_ACCESSIBLES) ); $GLOBALS['dossier_squelettes'] = $e.'squelettes'; if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f); } } ?&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/section&gt;&lt;section class=&#034;sommaire-section sommaire-section_niveau1 sommaire-section_h2&#034; aria-labelledby=&#034;Note-sur-les-sauvegardes-et-les-restaurations&#034;&gt;&lt;h2 class=&#034;h2&#034; id='Note-sur-les-sauvegardes-et-les-restaurations'&gt;Note sur les sauvegardes et les restaurations&lt;a class='sommaire-back sommaire-back-6' href='#s-Note-sur-les-sauvegardes-et-les-restaurations' title='Retour au sommaire'&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Chaque site copie ses fichiers de sauvegardes dans le r&#233;pertoire&lt;br class='autobr' /&gt;
/sites/premier_site/tmp/dump (ou /sites/premier_site/tmp/upload/&lt;i&gt;login&lt;/i&gt; pour les sauvegardes d'un administrateur restreint).&lt;br class='autobr' /&gt;
Les restaurations se font par le m&#234;me dossier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attention :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A l'heure actuelle, SPIP enregistre dans la base de donn&#233;es, pour ce qui concerne le dossier /IMG des sites mutualis&#233;s une adresse sites/premier_site/IMG/* au lieu de IMG/* comme pour un site SPIP seul.&lt;/p&gt;
&lt;p&gt;Une restauration ne fonctionnera donc que si elle s'effectue dans le site qui a cr&#233;&#233; la sauvegarde.&lt;/p&gt;
&lt;p&gt;Une astuce pour restaurer le site ailleurs consiste &#224; &#233;diter le fichier dump.xml et &#224; remplacer toutes les occurrences (&#224; l'exception de celles des d&#233;clarations dir_img et dir_logo dans l'ouverture de la balise spip) :
&lt;br /&gt;- sites/premier_site/IMG/&lt;/p&gt;
&lt;ul class=&#034;spip&#034; role=&#034;list&#034;&gt;&lt;li&gt; par (SPIP seul) : IMG/&lt;/li&gt;&lt;li&gt; ou (SPIP mutualis&#233;) : sites/mon_nouveau_site/IMG/&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Inversement, pour passer un SPIP seul dans un r&#233;pertoire mutualis&#233;, il faut remplacer toutes les occurrences de :
&lt;br /&gt;- IMG/
&lt;br /&gt;- par : sites/mon_site/IMG/&lt;/p&gt;&lt;/section&gt;&lt;/div&gt;
		&lt;hr /&gt;
		&lt;div class='rss_notes'&gt;&lt;div id=&#034;nb1&#034;&gt;
&lt;p&gt;&lt;span class=&#034;spip_note_ref&#034;&gt;[&lt;a href=&#034;#nh1&#034; class=&#034;spip_note&#034; title=&#034;Notes 1&#034; rev=&#034;appendix&#034;&gt;1&lt;/a&gt;] &lt;/span&gt;Pour information : ces proc&#233;dures ont &#233;t&#233; test&#233;es avec Apache 2.0.55 et PHP 5.1.2 sur serveur Ubuntu Dapper Drake ainsi que sur PHP 5.1.6 sur serveur Ubuntu Edgy Eft&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;
		
		</content:encoded>


		

	</item>



</channel>

</rss>
