PHP和MySql-如何使此插入查询起作用?

时间:2018-10-21 06:30:02

标签: php mysql

这是我的代码:

public function cadastrar(Family $family){

        var_dump($family); //just to verify


        $objDb = new db_con();
        $conn = $objDb->getConn();

        //REGISTER FAMILY INTO DATABASE
        $sql = "insert into family(family_declaracao_renda,
                                    familia_renda_mensal,
                                    family_assinatura_local,
                                    family_assinatura_dia,
                                    family_assinatura_mes,
                                    family_assinatura_ano,
                                    family_deficiente_presente,
                                    family_adaptacao_necessaria_imovel)
                            values( '$family->getDeclaracaoRendaFamiliar()',
                                    '$family->getRendaBrutaMensal()',
                                    '$family->getAssinaturaLocal()',
                                    '$family->getAssinaturaDia()',
                                    '$family->getAssinaturaMes()',
                                    '$family->getAssinaturaAno()',
                                    '$family->getDeficientePresente()',
                                    '$family->getAdaptacaoImovelNecessaria()')";

        //Executar query
        if (mysqli_query($conn, $sql)){
            echo 'SUCCESS!';
        } else {
            echo 'ERROR!';
        }

    }

所以我知道您可以将变量放在 VALUES('variable1','variable2')之间。我正在从该对象调用类方法,我想念什么?

2 个答案:

答案 0 :(得分:3)

准备查询,这是保护数据库免受SQLInjection类型攻击的最佳方法。它还解决了很多报价问题和其他问题。

$sql = 'INSERT INTO family(
    family_declaracao_renda,
    familia_renda_mensal,
    family_assinatura_local,
    family_assinatura_dia,
    family_assinatura_mes,
    family_assinatura_ano,
    family_deficiente_presente,
    family_adaptacao_necessaria_imovel
)VALUES(
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    ?,
    ?
)';
$stmt = mysqli_stmt_init($link);
mysqli_stmt_prepare($stmt, $sql);
mysqli_stmt_bind_param(
    $stmt,
    'ssssssss', //must be the same as number of argments, types s=string, i=int, d=double/float, b=blob 
    $family->getDeclaracaoRendaFamiliar(),
    $family->getRendaBrutaMensal(),
    $family->getAssinaturaLocal(),
    $family->getAssinaturaDia(),
    $family->getAssinaturaMes(),
    $family->getAssinaturaAno(),
    $family->getDeficientePresente(),
    $family->getAdaptacaoImovelNecessaria()
);

//Executar query
if (mysqli_stmt_execute($stmt)){
    echo 'SUCCESS!';
} else {
    echo 'ERROR!';
}

这并不难,即使MySqli程序界面很糟糕。考虑使用面向对象的界面,或切换到PDO(我的首选)。 MySqli的OOP界面要容易一些,但我不会为了篇幅而覆盖它。您可以在PHP.net上查找它,或者我确定那里有一些教程。

一个警告词,我已经好几年没有使用MySqli了(也许是6-8年),并且程序风格甚至更长了。因此,我无法保证将完全按照我在此处的方式工作。实际上,我认为我从未使用过MySqli的过程样式。当我离开mysql_(这样我就可以做准备好的语句)时,大约是在PHP5.3的中期(2010ish,也许是我完成网页设计大学的一年之后),我开始使用OOP(类和对象)几乎完全在我的代码中。因此,我刚从mysqli复制了大部分PHP.net代码。

http://php.net/manual/en/mysqli.prepare.php

在PDO中:

$sql = 'INSERT INTO family(
    family_declaracao_renda,
    familia_renda_mensal,
    family_assinatura_local,
    family_assinatura_dia,
    family_assinatura_mes,
    family_assinatura_ano,
    family_deficiente_presente,
    family_adaptacao_necessaria_imovel
)VALUES(
    :family_declaracao_renda,
    :familia_renda_mensal,
    :family_assinatura_local,
    :family_assinatura_dia,
    :family_assinatura_mes,
    :family_assinatura_ano,
    :family_deficiente_presente,
    :family_adaptacao_necessaria_imovel
)';
try{
    $stmt = mysqli_stmt_init($link);
    $Pdo->prepare($sql)->execute([
        ':family_declaracao_renda'          => $family->getDeclaracaoRendaFamiliar(),
       ':familia_renda_mensal'              => $family->getRendaBrutaMensal(),
       ':family_assinatura_local'           => $family->getAssinaturaLocal(),
       ':family_assinatura_dia'             => $family->getAssinaturaDia(),
       ':family_assinatura_mes'             => $family->getAssinaturaMes(),
       ':family_assinatura_ano'             => $family->getAssinaturaAno(),
       ':family_deficiente_presente'        => $family->getDeficientePresente(),
       ':family_adaptacao_necessaria_imovel'=> $family->getAdaptacaoImovelNecessaria(),
    ]);
}catch(PDOException $e){
    echo "PDOException[{$e->getCode()}] {$e->getMessage()} in {$e->getFile()} on {$e->getLine()}";
}

在PDO中,可以使用命名的占位符:name代替MySqli的?(在PDO中仍可以使用?)。我通常要做的是复制字段名称,并在其前面添加:。命名占位符使跟踪值的位置变得容易,数据数组的顺序(execute中使用的顺序也无关紧要)。如您所见,mysqli版本进行了大约4次调用,PDO版本仅进行了2次调用,并且通过方法链接$Pdo->prepare($sql)->execute(...),您甚至不需要将其放在另一行或设置局部变量。等效于此:

 //$Pdo->prepare($sql)->execute(...)
 $stmt = $Pdo->prepare($sql); //returns PDOStatement
 $stmt->execute(...); //makes a call on PDOStatement

因为$Pdo->prepare($sql)返回一个PDOStatement,如果我们不需要该对象做任何其他事情,我们可以在链中上一个方法的返回值上调用->execute(...)。我觉得我应该解释一下,因为您可能不习惯使用对象。但是,链接使代码保持整洁(没有多余的变量),这使跟踪事物(跟踪的事物更少)更加容易。

简而言之,在MySqli和PDO中都非常容易做到这一点,但是PDO具有很多优点,因此值得学习如何使用。更好的接口,更好的获取方法,命名的占位符,异常等...

干杯!

答案 1 :(得分:0)

$sql = 'INSERT INTO family(
    family_declaracao_renda,
    familia_renda_mensal,
    family_assinatura_local,
    family_assinatura_dia,
    family_assinatura_mes,
    family_assinatura_ano,
    family_deficiente_presente,
    family_adaptacao_necessaria_imovel
)VALUES(
    :family_declaracao_renda,
    :familia_renda_mensal,
    :family_assinatura_local,
    :family_assinatura_dia,
    :family_assinatura_mes,
    :family_assinatura_ano,
    :family_deficiente_presente,
    :family_adaptacao_necessaria_imovel
)';
try{
    $stmt = mysqli_stmt_init($link);
    $Pdo->prepare($sql)->execute([
        ':family_declaracao_renda'          => $family->getDeclaracaoRendaFamiliar(),
       ':familia_renda_mensal'              => $family->getRendaBrutaMensal(),
       ':family_assinatura_local'           => $family->getAssinaturaLocal(),
       ':family_assinatura_dia'             => $family->getAssinaturaDia(),
       ':family_assinatura_mes'             => $family->getAssinaturaMes(),
       ':family_assinatura_ano'             => $family->getAssinaturaAno(),
       ':family_deficiente_presente'        => $family->getDeficientePresente(),
       ':family_adaptacao_necessaria_imovel'=> $family->getAdaptacaoImovelNecessaria(),
    ]);
}catch(PDOException $e){
    echo "PDOException[{$e->getCode()}] {$e->getMessage()} in {$e->getFile()} on {$e->getLine()}";
}