Bonjour à tous,

Je travaille actuellement sur la création en local d'une webapplication de Gestion/Compta.
Je voudrai commencer mon projet par la chose la plus importante à mes yeux : la sauvegarde
de ma base de données !
J'ai donc suivi le tuto de Grafikart sur le dump Mysql avec composer mais j'ai un problème
dès le début !
Voici mon code :

try {
        require 'composer/vendor/autoload.php';         
        $dump = new \Ifsnop\Mysqldump\Mysqldump('compta','root','password');
        $dump->start('savebdd.sql');
    }catch (Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
    }

Voici le message d'erreur renvoyé :
mysqldump-php error: Empty DSN string

Bien entendu, dans mon arborescence aucun fichier 'savebdd.sql' n'apparait !
J'ai beau faire des recherches sur le net, je ne trouve rien qui explique cette erreur !

Pour l'instant, ma base de données 'compta' ne contient qu'une table 'utilisateurs'
elle même composée de 2 entrées...

Je vous remercie par avance des pistes ou solutions que vous pourriez me trouver !

Edit : Faut-il que j'aille faire un tour dans le fichier
/composer/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/mysqldump.php ?

19 réponses


Regarde la doc sur Github
la DSN doit ressembler à ça 'mysql:host=localhost;dbname=compta'

Merci Huggy,
Je pense trouver des pistes ici aussi :
https://packagist.org/packages/ifsnop/mysqldump-php
Important****
From version 2.0, connections to database are made using the standard DSN, documented in PDO connection string.

et ici :
http://php.net/manual/en/ref.pdo-mysql.connection.php

Je pense que la manière de se connecter à la bdd a changée depuis le tuto non ?

Nickel, ça devrait effectivement plutôt ressembler à ça ma connexion :

<?php
use Ifsnop\Mysqldump as IMysqldump;
try {
    $dump = new IMysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    $dump->start('savebdd.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}
?>

J'essaie dès que je suis à nouveau devant mon serveur !

Après avoir modifié mon code, changé de propriétaire sur mes dossiers et donné des
autorisations en écriture (chown root dump + chmod 777 dump), j'ai du mieux mais il y a
toujours un truc qui cloche ! ! !

Ceci fonctionne :

try {
        include_once('composer/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php');
        $dump = new Ifsnop\Mysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
        $dump->start('../dump/dump.sql');
    } catch (Exception $e) {
        echo 'mysqldump-php error: ' . $e->getMessage();
    }

Et ça non ! :

use Ifsnop\Mysqldump as IMysqldump;

try {
    $dump = new IMysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    $dump->start('../dump/dump.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}

Et en faisant ça :

use Ifsnop\Mysqldump\Mysqldump;

try {
    $dump = new Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    $dump->start('../dump/dump.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}

?
As-tu bien chargé composer ?

Oui ça doit être l'autoloader de composer qui n'est pas à jour
composer update

composer dump-autoload
plutôt ^^'

Oui j'ai du mal avec composer
faut dire qu'ils ne m'aident pas non plus en nommant leur commandes avec les pieds
le mec qui a pondu ça avait fumé
Moi quand je suis sobre, je pense à refresh, update ou reinit mais pas "dump-autoload"
du coup composer et moi ...
désolé pour cette disgression

Le problème semble se situer dans le namespace car sans cette partie le code fonctionne !
Voici ce qui tourne :

require_once 'composer/vendor/autoload.php'; 
    try {
        $dump = new Ifsnop\Mysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
        $dump->start('dump/dump.sql');
    } catch (\Exception $e) {
        echo 'mysqldump-php error: ' . $e->getMessage();
    }

Voici ce qui ne fonctionne pas : (copié/collé de l'exemple GitHub appliqué à mon cas)

require_once 'composer/vendor/autoload.php';
use Ifsnop\Mysqldump as IMysqldump; 
try {
    $dump = new IMysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    $dump->start('dump/dump.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}

Page blanche ! Je n'ai même pas de message d'erreur, même si je mets n'importe quoi comme mot de passe !

(PS : Je n'avais jamais utilisé composer il y a 3 jours !)
(J'ai déplacé mon dossier dump au même niveau que css, font, images...)

J'ai remarqué que lors d'un 'new', si on fait

namespace un\deux;
$toto = new machin\chose\Objet();
le namespace est rajouté
on a donc 
$toto = new  un\deux\machin\chose\Objet();  // ref relative au namespace courant

par contre si on préfixe d'un \, ça ne rajoute pas le namespace

$toto = new \machin\chose\Objet();  // ref absolue de la classe

Pour ton cas

require_once 'composer/vendor/autoload.php';  // suffit de l'appeler une fois dans index.php 
use Ifsnop\Mysqldump;    // pas besoin d'alias
try {
    // vu qu'on a fait un 'use', on peut appeler la classe directement
    $dump = new Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    // si on n'avait pas fait de use, il aurait fallut mettre une ref absolue
    // $dump = new \Ifsnop\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
    $dump->start('dump/dump.sql');
} catch (\Exception $e) {
    echo 'mysqldump-php error: ' . $e->getMessage();
}

déjà tu es sûr qu'il arriver à charger ton fichier ? Sur quel environnement travailles-tu ? wamp/lamp/mamp... ?

@Huggy :
Je suis désolé, mais ça ne fonctionne pas : j'ai viré mon code pour mettre le tien et je me retrouve
à nouveau avec une page blanche sans aucune indication sur l'erreur !

@AlexJM :
Je suis sous Mint 17.3 connecté à un PC transformé en serveur local
(Linux gescom 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux)
$ cat /etc/debian_version 8.4

Version PHP courante : 5.6.20-0+deb8u1

Apache/2.4.10 (Debian)

Composer version 1.1.2 2016-05-31 19:48:11
You are already using composer version 1.1.2 (stable channel).

Voici ce qui fonctionne chez moi
1) le composer.json

...
    "require": {
        "ifsnop/mysqldump-php": "^2.1"
    },
    "autoload": {
        "psr-4": {
            "App\\": "app",
            "Ifsnop\\Mysqldump\\": "vendor\\ifsnop\\mysqldump-php\\src\\Ifsnop\\Mysqldump"
        }
    }

refaire ensuite un composer dump-autoload
et dans le projet

use Ifsnop\Mysqldump\Mysqldump;  
$dump = new Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
$dump->start(ROOT .'/dump/dump.sql'); // penser a créer le dossier avant

Non normalement il faut pas l'ajouter dans l'autoloading

PS: personnellement le code fonctionne :/

Je n'ai pas d'autoload dans mon composer.json, voici son contenu :

{
    "name": "emrh/compta",
    "description": "WebApplication de gestion commerciale et comptabilité",
    "require": {
        "ifsnop/mysqldump-php": "^2.1"
    },
    "authors": [
        {
            "name": "emrh",
            "email": "emrh@test.fr"
        }
    ]
}

par contre dans ma page php, je l'appelle bien :

require_once 'composer/vendor/autoload.php'; 

Je pense que je vais rester comme ça

require_once 'composer/vendor/autoload.php'; 
    try {
        $dump = new Ifsnop\Mysqldump\Mysqldump('mysql:host=localhost;dbname=compta', 'root', 'password');
        $dump->start('dump/dump.sql');
    } catch (\Exception $e) {
        echo 'mysqldump-php error: ' . $e->getMessage();
    }

puisque ça fonctionne... J'aurais justé aimé comprendre pourquoi je ne peux pas reproduire à la
virgule près le tuto de Grafikart ! :-(

Tu as essayé de regarder les logs ?

Pour que l'autoloader fasse le lien entre un namespace et le chemin où trouver la classe
il peut soit le savoir par le composer.json (psr-4)
soit il utilise un tableau associatif (classmap) qui se trouve dans vendor/composer/autoload_classmap.php
il est conseillé d'utiliser la classmap en prod car c'est plus performant
pour générer la classmap on rajoute -o :

>composer -o dump-autoload
Generating optimized autoload files

D'après ce que j'ai compris, lors de la génération, composer doit ouvrir tous les fichiers situés dans vendor pour y repérer les namespaces, ça évite de le faire lors de l'exécution

Alors AlexJM & Huggy vous êtes trop sympa, vous avez vraiment envie que ça fonctionne
et je vous en remercie... Sauf que je ne connaissait pas Composer il y a 3 jours, je n'ai donc
aucune idée de l'endroit où lire les Logs et encore moins l'endroit où taper ">composer -o
dump-autoload..."
Est-ce sur le serveur dans le répertoire "composer" ?

En tous cas, en me baladant dans ces répertoires, j'ai trouvé un fichier test.php codé ainsi :

<?php
/*
for($i=0;$i<128;$i++) {
    echo "$i>" . bin2hex(chr($i)) . "<" . PHP_EOL;
}
*/

error_reporting(E_ALL);

include_once(dirname(__FILE__) . "/../src/Ifsnop/Mysqldump/Mysqldump.php");

use Ifsnop\Mysqldump as IMysqldump;

$dumpSettings = array(
    'compress' => IMysqldump\Mysqldump::NONE,
    'no-data' => false,
    'add-drop-table' => true,
    'single-transaction' => true,
    'lock-tables' => true,
    'add-locks' => true,
    'extended-insert' => false,
    'disable-keys' => true,
    'skip-triggers' => false,
    'add-drop-trigger' => true,
    'routines' => true,
    'databases' => false,
    'add-drop-database' => false,
    'hex-blob' => true,
    'no-create-info' => false,
    'where' => ''
    );

$dump = new IMysqldump\Mysqldump(
    "mysql:host=localhost;dbname=test001",
    "travis",
    "",
    $dumpSettings);

$dump->start("mysqldump-php_test001.sql");

Je m'en suis inspéré pour l'adapter à mon cas après un copier/coller, mais ça ne fonctionne toujours pas !

require_once 'composer/vendor/autoload.php'; 
    include_once("composer/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php");
    use Ifsnop\Mysqldump as IMysqldump;
    $dump = new IMysqldump\Mysqldump("mysql:host=localhost;dbname=gescom","root","aaaaaaaa");
    $dump->start("dump/dump.sql");

Pas de problème ;)

include_once("composer/vendor/ifsnop/mysqldump-php/src/Ifsnop/Mysqldump/Mysqldump.php");

Le but de l'autoloader est justement de ne pas devoir faire ce genre de choses ^^
Dans ton dossier composer, tape la commande :

composer dump-autoload

Et pour les logs PHP, c'est les logs de ton serveur, parfois les erreurs ne s'affichent pas mais sont loggées (comme sur mamp)