Bonjour,

Voilà, je créer un install.php qui sera censé créer la base de donnée d'un site web directement. Pour cela je créer une connexion avec mysql avec les variables renseignées par l'utilisateur (hôte, username et pass).
QUand je test en local, j'arrive bien à executer les requêtes de création de DATABASE/TABLE etc..
Cependant il faut savoir que l'utilisateur va vouloir exectuer ce fichier sur son FTP par exemple. Et la j'ai plus rien, impossible de se connecter à la BDD.

Voici le code d'erreur :

DB ERROR: SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: YES)

Mon code :

  $dbh = new PDO("mysql:host=".$_POST['db_host'], $_POST['db_username'], $_POST['db_password']);

Cordialement,

18 réponses


AlphA
Auteur
Réponse acceptée

Bonjour à tous,
Pour commencer merci de vos réponses et de porter un intêret à mon problème.

@BetaWeb, en effet le PDO n'a pas besoin d'une base de donnée en paramètre puisque ce n'est pas du tout l'intêret de mon fichier qui est censé la créer par la suite.

@Huggy, je confirme qu'en passant par un terminal et en testant une connexion mysql avec "mysql -h XXX -u XXX -p" je n'ai aucuns problème pour créer des bases ou des tables.

On m'a également dit que mon code pouvait présenter des failles d'injonctions SQL. SI vous avez des suggestions à ce sujet?

EDIT; j'ai progressé un petit peu, en fait j'arrive bien à me connecter au sql quand je met le fichier sur min FTP, aucune erreur. Sauf que ça ne me crée rien. Pour me connecter il fallait que je mette localhost si je suis sur mon FTP..

Deuxième EDIT : J'ai trouvé :) !
En fait, quand vous utilisez votre fichier sur un FTP, pour se connecter à la DB il faut renseigné le db_host par localhost et non l'IP de la machine. De plus j'avais des problèmes de permissions dans la bdd, je sais pas pourquoi mais en fait je ne pouvais pas créer de bdd. SI un seul cas passait, je pouvais effectivement créer la bdd "test" et rien de plus, tout les autres cas ne fonctionnent pas. Du coup avec le db_name à "test" tout fonctionne bien.

Cordialement,

Salut,

L'erreur parle d'elle-même.
La connexion attend un mot de passe, et de deux choses l'une: soit le mot de passe renseigné est faux, soit aucun mot de passe n'est renseigné.
Comment est appelé le script installer.php ? Via un formulaire ?

AlphA
Auteur

oui par formulaire, tout fonctionne impec sur le local. C'est pas une erreur qui provient des données renseignées, en tout cas pas de l'hôte, de l'user ou password. Tout est juste et fonctionne très bien. C'est vraiment quand je test le fichier sur le FTP que ça affiche cette erreur. COmme si le mettre sur un hebergeur pouvait le gêner.

Comme je t'ai dit, c'est que le mot de passe permettant la connexion à la BD doit être faux (ce n'est évidemment pas le même qu'en local).

AlphA
Auteur

Comment ça ce n'est évidemment pas le même que en local? Si j'essaie à partir du fichier stocker dans le FTP à me connecter sur mon local, les identidiants restent les mêmes...

Pas forcément ! La BD distante est paramétrée différemment, peut-être nommée différemment et a ses propres identifiants de connexion.
Tu ne te connecte pas à ton facebook avec les identifiants de ton voisin, là c'est pareil ! ^^

Tu dois avoir une petite explication sur les couches réseaux et leur accès via internet
tu as ton ordinateur : 127.0.0.1
ton réseau local : 192.168.x.x
et internet : 80.x.x.x.x.x

Donc quand tu es sur internet (80.x.x.x.x.x, valable dans le cas de ton serveur), tu ne peux pas accèder à ton réseau local, ni à ton ordinateur, mais l'inverse oui.

Donc dans ton cas précis : tu utilise une base de donnée pour ton developpement jusque la ok.
Seulement tu ne peux pas utiliser cette même base de donnée pour ton serveur, car ta base de dev est sur ton ordinateur.
Donc pour utiliser la base tu dois crée la base sur ton serveur, et donc renseigner les identifiants de la base serveur dans ton script.

AlphA
Auteur

@thehawk_
**J'ai bien essayé de me connecter directement sur le serveur ou mon fichier était. Malheureusement il n'arrive pas à se connecter même avec les bons identidfiants (hôte, username, password).

Imaginons mon serveur est à l'adresse : 01.00.01.11
Mot de passe utilisateur de la BDD /!\ associée au serveur, donc celle du local /!\ : alpha et comme pass : alpha_pass

Je met mon install.php sur mon ftp hebergé sur le serveur 01.00.01.11, et remplie mes ligne de codes avec les bonne variables. Ceci étant fait il n'arrive pas et me retourne le code d'erreur. Comment puis je proceder pour y acceder depuis mon .php ? D'ou le rôle d'un installeur.

Alors ta base est mal configurer, ou tu as un autre soucis, mais vérifie bien tes identifiants car avoir un env de dev et un env de prod avec les meme mot de passe, meme adresse ip c'est rare, vérifie de ce coté là.

AlphA
Auteur

Bah je n'ai rien de plus, mon hebergeur m'a fourni les accès à ma BDD et puis c'est tout. Donc je devrai au moins pouvoir y accèder à travers mon .php non ?

Aller je met mon code, espérant que l'on puisse me débloquer :)

{
        $dbh = new PDO("mysql:host=".$_POST['db_host'], $_POST['db_username'], $_POST['db_password']);

        $dbh->exec("CREATE DATABASE ".$_POST['db_name'].";");
        $dbh->exec("USE ".$_POST['db_name'].";");
        $dbh->exec("CREATE TABLE admin (id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, username VARCHAR(255) UNIQUE, password VARCHAR(255));");
        $dbh->exec("INSERT INTO admin (username, password) VALUES ('".$_POST['adm_username']."','".$_POST['adm_password']."');");

        echo "BDD created!";
    }

Tu peux coller ton formulaire html ?

AlphA
Auteur
    if (empty($_POST['db_host']) OR empty($_POST['db_name']) OR empty($_POST['db_username']) OR empty($_POST['db_password']))
        { ?>
    <?php include("content/head.php"); ?>
                <div class="container install-container text-center">
                    <div class="install-container-border">
                        <h1 class="exo-bold">
                             <a><img src="/../img/alpha-logo-small.png"></a></br>
                             <small class="hvr-shadow-radial">Installation</small></br></br>
                             <div style="padding-right: 100px; padding-left: 100px">
                             <div class="install-progress">
                                <div class="install-progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 50%;">50%</div>
                            </div></div>
                        </h1>
                        <div class="text-left" style="padding-left: 150px">
                            <form method="post" action="install.php" style="font-family: raleway !important;">
                                <p>
                                    <div style="height: 30px">Database Host:   <input type="text" name="db_host" style="height: 22px"/></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['db_host']))  {;?> <div class="alert-install alert-danger" role="alert">Database host is required.</div> <?php } ?>
                                    <div style="height: 30px">Database Name:   <input type="text" name="db_name" style="height: 22px"/></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['db_name']))  {;?> <div class="alert-install alert-danger" role="alert">Database name is required.</div> <?php } ?>
                                    <div style="height: 30px">Database Username:   <input type="text" name="db_username" style="height: 22px"/></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['db_username']))  {;?> <div class="alert-install alert-danger" role="alert">Database username is required.</div> <?php } ?>
                                    <div style="height: 30px">Database Password:   <input type="password" name="db_password" style="height: 22px"/></br></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['db_password']))  {;?> <div class="alert-install alert-danger" role="alert">Database password is required.</div> <?php } ?>
                                    <div style="height: 30px">Admin Username:   <input type="text" name="adm_username" style="height: 22px"/></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['admin_username']))  {;?> <div class="alert-install alert-danger" role="alert">Admin username is required.</div> <?php } ?>
                                    <div style="height: 30px">Admin Password:   <input type="password" name="adm_password" style="height: 22px"/></br></div>
                                        <?php if (!empty($_POST['try']) && empty($_POST['admin_password']))  {;?> <div class="alert-install alert-danger" role="alert">Admin password is required.</div> <?php } ?>
                                    <input type="hidden" name="try" value="try"/>
                                    <div style="height: 50px; margin-top: 50px;">
                                        <input type="submit" value="Confirm"style="font-family: raleway !important;"class="btn btn-default btn-alpha text-center"/>
                                    </div>
                                </p>
                            </form></br></br>
                        </div>
                    </div>
                </div>
        <?php }
    else
    {
        $dbh = new PDO("mysql:host=".$_POST['db_host'], $_POST['db_username'], $_POST['db_password']);

        $dbh->exec("CREATE DATABASE ".$_POST['db_name'].";");
        $dbh->exec("USE ".$_POST['db_name'].";");
        $dbh->exec("CREATE TABLE admin (id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, username VARCHAR(255) UNIQUE, password VARCHAR(255));");
        $dbh->exec("INSERT INTO admin (username, password) VALUES ('".$_POST['adm_username']."','".$_POST['adm_password']."');");

        echo "BDD created!";
    }

?>

Lorsque tu instancies ton objet PDO, tu ne lui donne pas le nom de la base de donnée à laquelle il faut se connecter.
Je t'invite à relire la documentation de PDO : http://php.net/manual/fr/pdo.construct.php, et notamment l'exemple #1

Il me semble que dbname dans le dsn est optionnel, ce qui permet de créer des bases depuis PHP avec PDO
http://php.net/manual/fr/ref.pdo-mysql.connection.php

De toute manière il nous dit qu'en local ça fonctionne, donc soit le dbuser n'a pas les droits de création, soit le mot de passe n'est pas bon ...

Il faut vérifier si l'hébergeur authorise la création d'une base de données, car souvent on en a une par défaut et il faut faire avec.
Si on a en besoin d'une autre, on utilise la même mais en mettant des préfixes de table (cf Wordpress, joomla, Prestashop...)

@ADessi effectivement ;)

Il faudrait aussi vérifier les privilèges sur tes bases de données.

Content que tu ais résolu ton pb
pour info regarde quels comptes t'autorisent à te connecter
root@localhost ne permet de se connecter QUE DEPUIS localhost
root@ip permet de se connecter depuis une ip précise
root@% permet tous les hotes

pour l'injection SQL, ton cas est particulier car il concerne des ordres DDL
les requêtes préparées ne fonctionnent pas , et toutes les fonctions qui protègent les quotes ne servent à rien.
le risque est de pouvoir enchainer plusieurs ordres à la suite en insérant un point-virgule
je n'ai pas de solution mis à part supprimer les ';' et les espaces de tes variables.

Edit : pdo propose la constante suivante
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false
à rajouter dans le tableau d'options

AlphA
Auteur

Merci bien.