web-dev-qa-db-fra.com

Utiliser les méthodes Magento pour écrire des requêtes d'insertion avec soin pour l'injection SQL

J'utilise la fonctionnalité de Magento pour insérer et mettre à jour des requêtes. Mon exigence est que je veuille m'occuper de l'injection SQL, lors de ce type de requêtes. Mais je ne peux pas trouver comment Magento fait cela. Je fournis un échantillon de départ. Veuillez me fournir un exemple complet.

<?php
$write = Mage::getSingleton("core/resource")->getConnection("core_write");
$sql = "INSERT INTO Mage_Example (Name, Email, Company, Description, Status, Date)
    VALUES ('$name', '$email', '$company', '$desc', '0', NOW())";
?>

Maintenant, je veux changer la requête ci-dessus pour empêcher l'éventuelle injection SQL. Je ne veux pas utiliser la fonction intégrée par défaut "mysql_real_escape_string()" de PHP. Quelqu'un peut-il me fournir une solution utile, en utilisant le gestionnaire de bases de données "$write"?.

Toute aide est grandement appréciée.

27
Knowledge Craving

D'accord, j'ai un peu recherché celui-ci. Si vous pouvez obtenir une instance d'un DB_Adapter (dont je pense que l'appel de ressource va revenir), cela ne devrait pas être trop difficile. Au fond, Magento est basé sur Zend Framework, et l'adaptateur DB en particulier est issu de Zend_Db_Adapter , vous pouvez donc utiliser ces méthodes gratuitement. Voir le lien avant pour plus d'exemples, mais voici la syntaxe fournie dans la documentation, qui devrait échapper automatiquement à votre entrée:

$write = Mage::getSingleton("core/resource")->getConnection("core_write");

// Concatenated with . for readability
$query = "insert into mage_example "
       . "(name, email, company, description, status, date) values "
       . "(:name, :email, :company, :desc, 0, NOW())";

$binds = array(
    'name'    => "name' or 1=1",
    'email'   => "email",
    'company' => "company",
    'desc'    => "desc",
);
$write->query($query, $binds);

Encore une fois, consultez la documentation pour plus d'informations.


METTRE À JOUR:

J'ai changé l'exemple ci-dessus. L'objet que vous récupérez avec votre requête core_write est un objet PDO qui expose une méthode query (voir ci-dessus) qui vous permettra d'utiliser des requêtes paramétrées. C'est BY FAR une meilleure approche que d'essayer d'utiliser quelque chose comme mysql_real_escape_string pour le nettoyage des données, et j'ai testé l'exactitude du code ci-dessus. Notez que, contrairement à la plupart des requêtes paramétrées MySQL, la liaison se fait avec: labels, et aussi que vous n'avez pas besoin de devis pour vos vars.

En réponse à votre autre point, et comme indiqué ci-dessous, la "bonne" façon de le faire dans Magento n'est pas du tout d'utiliser des requêtes directes. Les modèles d'objets Magento sont bien développés et destinés à abstraire ce genre de détails d'implémentation loin de vous, car vous ne devriez pas avoir à vous en préoccuper. Pour le faire "correctement", créez un nouveau modèle basé sur une base de données et enregistrez le mal de tête.

59
Joseph Mastey

J'utilise ceci pour insérer plusieurs lignes dans la table

$table = Mage::getSingleton('core/resource')->getTableName('table_name');
$rows = array(
   array('cal_1'=>'value','cal_2'=>'value','cal_3'=>'value'),
   array('cal_1'=>'value','cal_2'=>'value','cal_3'=>'value')
);

public function insertRows($table,$rows)
{
   $write = Mage::getSingleton('core/resource')->getConnection('core_write');
   $write->insertMultiple($table,$rows);
}
13
user3409501

je suppose que s'échapper du $ name, $ email et d'autres variables sera suffisant.

jetez un oeil à la fonction mysql_real_escape_string .

2
0xAF

Dans le fichier de ressources.

public function saveToTable($param){

$table = $this->getMainTable(); 

$this->_getWriteAdapter->insert($table,array(
          'col_1'=>$param['data1']
          'col_2'=>$param['data2']
          'col_3'=>$param['data3']
      ));
}

renvoie le nombre de lignes affectées.

2
Ricky Sharma