php $ _POST获取值 - 不是最好的方法

时间:2011-02-27 21:12:14

标签: php

编辑:

非常感谢你的回答,你真的很惊讶我的智慧:)

我试图继续对TuteC的代码进行一些改动,但无法确定如何使其正常工作:

$valor = $_POST['valor'];

$post_vars = array('iphone3g1', 'iphone3g2', 'nome', 'iphone41', 'postal', 'apelido');
foreach($post_vars as $var) {
    $$var = "'" . mysql_real_escape_string($_POST[$var]). "', ";
}

$sql = "INSERT INTO clientes (iphone3g1, iphone3g2, nome, iphone41, postal, apelido, valor) VALUES ($$var '$valor')";
$query= mysql_query($sql);

我知道代码上有一点作弊,我需要使用子字符串,因此$$ var不会输出“,”在我需要值的末尾,而是我试图插入一个变量是一个值($ valor = $ _POST ['valor'];) 出了什么问题?

对于那些试图帮助我的人,非常感谢,我在stackoverflow上和你一起学到很多东西。

我有一个包含多个字段值的表单,当尝试编写一个读取这些值的php文件时,它出现了一个很小的问题:

$codigounico= md5(uniqid(rand()));
$modelo=$_POST['selectName'];
$serial=$_POST['serial'];
$nif=$_POST['nif'];
$iphone3g1=$_POST['iphone3g1'];
$iphone3g2=$_POST['iphone3g2'];
$iphone3g3=$_POST['iphone3g3'];
$iphone3g4=$_POST['iphone3g4'];
$iphone3gs1=$_POST['iphone3gs1'];
$iphone3gs2=$_POST['iphone3gs2'];
$iphone3gs3=$_POST['iphone3gs3'];
$iphone3gs4=$_POST['iphone3gs4'];
$iphone41=$_POST['iphone41'];
$iphone42=$_POST['iphone42'];
$iphone43=$_POST['iphone43'];
$iphone44=$_POST['iphone44'];
$total=$_POST['total'];
$valor=$_POST['valor'];
$nome=$_POST['nome'];
$apelido=$_POST['apelido'];
$postal=$_POST['postal'];
$morada=$_POST['morada'];
$notas=$_POST['notas'];

$sql="INSERT INTO clientes (postal, morada, nome, apelido, name, serial, iphone3g1, iphone3g2, iphone3g3, iphone3g4, total, valor, iphone3gs1, iphone3gs2, iphone3gs3, iphone3gs4, iphone41, iphone42, iphone43, iphone44, nif, codigounico, Notas)VALUES('$postal', '$morada', '$nome', '$apelido', '$modelo', '$serial', '$iphone3g1', '$iphone3g2', '$iphone3g3', '$iphone3g4', '$total', '$valor', '$iphone3gs1', '$iphone3gs2', '$iphone3gs3', '$iphone3gs4', '$iphone41', '$iphone42', '$iphone43', '$iphone44', '$nif', '$codigounico', '$notas')";
$result=mysql_query($sql);

这是一个非常难以维护的代码,

我可以让自己的生活更轻松吗?

8 个答案:

答案 0 :(得分:4)

要限制您导入"导入",您可以执行以下操作:

$post_vars = array('iphone3g1', 'iphone3g2', '...');
foreach($post_vars as $var) {
    $$var = mysql_real_escape_string($_POST[$var]);
}

编辑:addslashes更改了mysql_real_escape_string(感谢@Czechnology)。

答案 1 :(得分:4)

我看到的问题是重复四次相同的名字。这就是我将它减少到两次的情况(你可以把它减少到一个更多的重复)。

$sql = 'INSERT INTO clientes (postal, morada, nome, apelido, name, serial, iphone3g1, iphone3g2, iphone3g3, iphone3g4, total, valor, iphone3gs1, iphone3gs2, iphone3gs3, iphone3gs4, iphone41, iphone42, iphone43, iphone44, nif, codigounico, Notas) VALUES(:postal, :morada, :nome, :apelido, :modelo, :serial, :iphone3g1, :iphone3g2, :iphone3g3, :iphone3g4, :total, :valor, :iphone3gs1, :iphone3gs2, :iphone3gs3, :iphone3gs4, :iphone41, :iphone42, :iphone43, :iphone44, :nif, :codigounico, :notas)';

preg_match_all('/:(\w+)/', $sql, $inputKeys);
$tokens = $inputKeys[0];
$values = array_map($inputKeys[1], function($k){
    return mysql_real_escape_string($_POST[$k]);
});
$sql = str_replace($tokens, $values, $sql);
$result = mysql_query($sql);

根据您希望如何分离逻辑,反向方法可能更有用,您可以指定键名数组并迭代它以生成SQL字符串。

<?php

$inputKeys = array('postal', 'morada', 'nome', 'apelido', 'name', 'serial', 'iphone3g1', 'iphone3g2', 'iphone3g3', 'iphone3g4', 'total', 'valor', 'iphone3gs1', 'iphone3gs2', 'iphone3gs3', 'iphone3gs4', 'iphone41', 'iphone42', 'iphone43', 'iphone44', 'nif', 'codigounico', 'Notas');

$keyList = '(' . implode(',', $inputKeys) . ')';
$valueList = 'VALUES (';
foreach ($inputKeys as $k) {
    $valueList .= mysql_real_escape_string($_POST[$k]);
    $valueList .= ',';
}
$valueList = rtrim($valueList, ',');
$valueList .= ')';

$sql = 'INSERT INTO clientes '.$keyList.' '.$valueList;
$result = mysql_query($sql);

这种方法可以将键的出现次数减少到一次,并且可能更适合您的应用程序。

答案 2 :(得分:2)

TuteC有一个很好的目标,但没有详细说明。

这让我很奇怪,为什么没有人有现成的解决方案,但必须在飞行中设计它。之前没有人遇到过同样的问题? 为什么大多数人只试图解决部分问题,只获得变量。

目标不是获取变量。
目标是获得一个查询。所以,给自己一个查询。

//quite handy way to define an array, saves you from typing zillion quotes
$fields = explode(" ","postal morada nome apelido name serial iphone3g1 iphone3g2 iphone3g3 iphone3g4 total valor iphone3gs1 iphone3gs2 iphone3gs3 iphone3gs4 iphone41 iphone42 iphone43 iphone44 nif codigounico Notas");

$sql    = "INSERT INTO clientes SET ";
foreach ($fields as $field) {
  if (isset($_POST[$field])) {
    $sql.= "`$field`='".mysql_real_escape_string($_POST[$field])."', ";
  }
}
$sql = substr($set, 0, -2); 

此代码将为您创建一个查询,而无需多次重复相同的字段名称。

但这仍然不是你能做的所有改进 一个非常简洁的东西叫做一个函数。

function dbSet($fields) {
  $set    = '';
  foreach ($fields as $field) {
    if (isset($_POST[$field])) {
      $set.="`$field`='".mysql_real_escape_string($_POST[$field])."', ";
    }
  }
  return substr($set, 0, -2); 
}

将此函数放入包含在所有脚本中的代码库中(您有一个,不是吗?) 然后将其用于插入和更新查询:

$_POST['codigounico'] = md5(uniqid(rand()));//a little hack to add custom field(s)
if ($action=="update") {
  $id  = intval($_POST['id']);
  $sql = "UPDATE $table SET ".dbSet($fields)." WHERE id = $id";
}
if ($action=="insert") {
  $sql = "INSERT $table SET ".dbSet($fields);
}

因此,您的代码变得非常短且可靠,甚至可以重复使用 您需要更改以处理另一个表的唯一方法是$ fields数组。

您的数据库似乎计划不周,因为它包含看似重复的字段(iphone *)。您必须规范化数据库。

在我的问题中可以找到与预准备语句一起使用的相同方法:Insert/update helper function using PDO

答案 3 :(得分:1)

你可以使用一个相当难看的PHP部分称为变量变量,但它通常被认为是一种糟糕的编码实践。您可以同时包含数据库转义。代码看起来像:

foreach($_POST as $key => $value){
    $$key = mysql_real_escape_string($value);
}

变量变量手册部分说它们不适用于像$ _PATH这样的超级全局,但我认为它可能适用于这种情况。我不是现在可以测试的地方。

答案 4 :(得分:0)

PHP: extract

请注意,并确保在使用前清理数据。

答案 5 :(得分:0)

$set = array();
$keys = array('forename', 'surname', 'email');
foreach($keys as $val) {
  $safe_value = mysqli_escape_string($db, $_POST[$val]);
  array_push($set, "$val='$safe_value'");
}
$set_query = implode(',', $set);

然后使您的MySQL查询类似UPDATE table SET $set_query WHERE...INSERT INTO table SET $set_query


如果您需要验证,修剪等,请执行之前上述代码,如下所示:

$_POST["surname"] = trim($_POST["surname"];

答案 6 :(得分:-1)

实际上,您可以通过使代码更复杂来使您的生活更轻松 - 在插入数据库之前转义输入!

$sql = 
  "INSERT INTO clientes SET
    "postal = '" . mysql_real_escape_string($_POST['postal']) . "', ".
    "morada = '" . mysql_real_escape_string($_POST['morada']) . "', ".
    ...

答案 7 :(得分:-1)

首先,我建议你创建一个这样的键值数组:

$newClient = array(
  'codigounico' => md5(uniqid(rand())),
  'postal'      => $_POST['postal'],
  'modelo'      => $_POST['selectName'],
  ...
);

在此数组中是您的MySQL表的列名称。 在您提供的代码中,并非每个字段都是从POST数组中复制的(有些是计算的,而POST的某些键与表列名不相同),因此您应该使用灵活的方法。 您仍应指定所有列和值,但只能指定一次,因此代码仍可维护,如果有人向您发送了损坏的POST,您将不会遇到任何安全错误。至于我,它看起来更像配置而不是编码。

然后我建议你写一个类似的函数:

function buildInsertQuery($tableName, $keyValue) {
  $result = '';
  if (!empty($keyValue)) {
    $delimiter = ', ';
    $columns = '';
    $values = '';
    foreach ($keyValue as $key => $value) {
      $columns .= $key . $delimiter;
      $values .= mysql_real_escape_string($value) . $delimiter;
    }
    $columns = substr($columns, 0, -length($delimiter));
    $values = substr($values, 0, -length($delimiter));
    $result = 'INSERT INTO `' . $tableName . '` (' . $columns . ') VALUES (' . $values . ')';
  }
  return $result;
}

然后您只需使用一个函数调用即可构建查询:

$query = buildInsertQuery('clientes', $newClient);