2010-08-26 9 views
26

J'utilise la fonctionnalité de Magento pour insérer des requêtes de mise à jour &. Mon exigence est que je veux prendre soin de SQL Injection, lors de ces types de requêtes. Mais je suis incapable de trouver comment Magento fait cela. Je fournis un échantillon de départ. S'il vous plaît, donnez-moi un exemple complet.Utilisation des méthodes Magento pour écrire des requêtes d'insertion avec soin pour l'injection SQL

<?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'injection SQL possible. Je ne veux pas utiliser la fonction intégrée "mysql_real_escape_string()" par défaut de PHP. Quelqu'un peut-il s'il vous plaît me fournir une solution utile, en utilisant le "$write" DB Handler.

Toute aide est grandement appréciée.

+0

$ réduction de valeur> citation ($ string); – ppostma1

Répondre

55

Bon, j'ai fait une recherche sur celui-ci. Si vous pouvez obtenir une instance d'un DB_Adapter (que je crois que l'appel de ressource retournera), cela ne devrait pas être trop difficile. Au fond, Magento est basé sur Zend Framework, et l'adaptateur de base de données descend spécifiquement de Zend_Db_Adapter, donc vous pouvez utiliser ces méthodes gratuitement. Voir le lien avant pour plus d'exemples, mais voici la syntaxe fournie dans la documentation, qui devrait échapper à votre entrée automagiquement:

$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, voir la documentation pour plus d'informations.


MISE À 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 DE loin une meilleure approche que d'essayer d'utiliser quelque chose comme mysql_real_escape_string pour la désinfection des données, et j'ai testé le code ci-dessus pour l'exactitude. Notez que, contrairement à la plupart des requêtes paramétrées MySQL, la liaison est faite avec: labels, et aussi que vous n'avez pas besoin de guillemets 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 d'utiliser des requêtes directes du tout. Les modèles d'objet Magento sont bien développés et ont pour but de vous faire abstraction de ce type de détails d'implémentation, car vous ne devriez pas avoir à vous en soucier. Pour le faire "correctement", créez un nouveau modèle basé sur la base de données et enregistrez le mal de tête.

+0

Merci pour l'info. Mais je suis toujours à la noirceur. Corrigez-moi si j'ai tort, s'il-vous plait.Tout d'abord, vous avez utilisé l'objet "' $ db' "et utilisé sa méthode" 'insert()' "pour insérer l'enregistrement de données dans la table" bugs ". Maintenant ce que je veux vraiment, c'est utiliser l'objet "' $ write' "(de ma question) au lieu de cet objet" '$ db'". ** S'il vous plaît me traiter comme un novice dans cette architecture "Zend_Db". ** Merci encore pour votre temps, mais pouvez-vous s'il vous plaît essayer de le résoudre en fonction de ma question? Aussi s'il vous plaît prenez soin de fournir la solution par Magento spécifiquement et non "Zend_Db", bien que je comprenne la relation entre les deux. –

+0

Pour être juste, la méthode Magento n'est pas d'exécuter directement le SQL directement. Définissez un modèle de données (ou un modèle EAV) et insérez-le de cette façon. en regardant les autres éléments que vous avez mentionnés, je vais essayer de modifier l'exemple. –

+0

Merci beaucoup pour cette réponse si informative et particulière. En raison de mes pièces jointes à d'autres œuvres, je ne suis actuellement pas disponible pour utiliser votre exemple et tester mon application, mais je vais certainement utiliser votre réponse dans la semaine à venir seulement. Alors s'il vous plaît donnez-moi un peu de temps, pour marquer cela comme la réponse appropriée. Merci encore. –

2

Je suppose que d'échapper le nom de $, $ email et d'autres variables seront suffisantes. Regardez la fonction mysql_real_escape_string.

+0

S'il vous plaît vérifier ma question éditée. Je ne veux pas utiliser de fonction PHP intégrée; seulement les méthodes de Magento. S'il vous plaît fournir plus d'option et merci pour votre essai. –

+0

@KC - désolé, je ne suis pas familier avec magento. Je répondais juste et chose évidente, mais il semble que ce n'est pas si évident après tout;) – 0xAF

+0

C'est bon, pour votre effort. +1 –

2

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.

13

J'utilise ceci pour insérer plusieurs lignes à 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); 
}