php $ _POST para obter valores – não a melhor maneira

EDITAR:

Muito obrigado por suas respostas, você realmente me surpreende com tanta sabedoria 🙂

Estou tentando retransmitir o código do TuteC um pouco mudado, mas não consigo descobrir como fazê-lo funcionar corretamente:

$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); 

Eu sei que há um pouco de trapaça no código, eu precisaria usar substring para que o $$ var não emitiria um “,” no final em que eu preciso dos valores, eu tentei inserir uma variável que seja um valor ($ valor = $ _POST [‘valor’];) O que está acontecendo de errado?

E para os outros que tentaram me ajudar, muito obrigado, estou aprendendo muito com você aqui no stackoverflow.

Eu tenho um formulário com vários valores de campo, ao tentar escrever um arquivo php que lê esses valores, surgiu uma mostruosidade:

 $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); 

Este é um código muito difícil de manter,

Posso facilitar minha vida?

Para restringir quais variables ​​POST você “importar”, você pode fazer algo como:

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

EDITAR: addslashes por mysql_real_escape_string (obrigado @Czechnology).

A questão que vejo é a repetição dos mesmos nomes quatro vezes. É assim que eu reduziria isso para duas ocorrências (você poderia soltá-lo para um com mais finagling).

 $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); 

Dependendo de como você deseja separar sua lógica, uma abordagem invertida pode ser mais útil, onde você especificará a matriz de nomes de chaves e itera sobre isso para gerar a string 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); 

Essa abordagem descarta as ocorrências das chaves para uma e provavelmente será mais natural com sua aplicação.

O TuteC teve um bom objective, mas falhou em detalhes.

Isso me faz pensar, porque ninguém tem uma solução pronta, mas teve que planejá-la sobre a marcha. Ninguém enfrentou o mesmo problema antes?
E por que a maioria das pessoas tenta resolver apenas uma parte do problema, obtendo apenas variables.

O objective não é obter variables.
O objective é obter uma consulta. Então, obtenha uma consulta.

 //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); 

Este código irá criar uma consulta sem chato, repetindo o mesmo nome de campo muitas vezes.

Mas isso ainda não é todas as melhorias que você pode fazer.
Uma coisa realmente agradável é chamada de function.

 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); } 

Coloque esta function em sua biblioteca de código sendo incluída em todos os seus scripts (você tem um, não é?) e depois use-o para consultas de inserção e atualização:

 $_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); } 

Então, seu código torna-se extremamente curto e confiável e até mesmo reutilizável.
A única coisa que você precisa mudar para lidar com outra tabela é $ fields array.

Parece que seu database não está bem planejado, pois contém campos aparentemente repetitivos (iphone *). Você precisa normalizar seu database.

A mesma abordagem para usar com declarações preparadas pode ser encontrada nesta minha pergunta: Insira / atualize a function auxiliar usando DOP

Você poderia usar uma parte bastante feia do PHP chamada variables ​​variables, mas geralmente é considerada uma prática de codificação pobre. Você pode include seu database escapando ao mesmo tempo. O código seria algo como:

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

As variables ​​variables ​​seção manual dizem que não funcionam com superglobais como $ _PATH, mas acho que isso pode funcionar neste caso. Eu não estou em algum lugar onde eu posso testar agora.

PHP: extrato

Seja cuidadoso e certifique-se de limpar os dados antes de usá-lo.

 $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); 

Em seguida, faça sua consulta MySQL algo como UPDATE table SET $set_query WHERE... ou INSERT INTO table SET $set_query .


Se você precisar validar, cortar, etc, faça isso antes do código acima, como este:

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

Na verdade, você poderia tornar a sua vida mais fácil, tornando seu código um pouco mais complicado – escape da input antes de inserir no database!

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

Primeiro, eu recomendo que você crie uma matriz de valores-chave como esta:

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

Nesta chave da matriz, a coluna é a sua tabela MySQL. No código que você forneceu, nem todos os campos são copiados diretamente da matriz POST (alguns são calculados e algumas chaves do POST não são iguais aos nomes das colunas das tabelas), então você deve usar um método flexível. Você ainda deve especificar todas as colunas e valores, mas apenas uma vez, de modo que o código ainda seja mantido e você não terá erros de segurança se alguém lhe enviar um POST quebrado. Quanto a mim, parece mais configuração do que codificação.

Então eu recomendo que você escreva uma function semelhante a esta:

 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; } 

E então você pode simplesmente criar sua consulta com apenas uma chamada de function:

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