发布不与复选框形式工作

时间:2017-05-13 23:44:44

标签: php sql class oop

我在使用OOP CRUD方法时遇到了一些麻烦。我的POST方法不是检索数据或将数据发布到数据库。而且我不确定在哪里看,因为它不会显示任何错误。

表格上方的逻辑:

$id = $_GET['id'];


//Add Board
$b = new Board();
$userID = $_SESSION['id'];
$boards= $b->loadBoards($userID);

if(isset($_POST['addBoard'])){
try{
    $sB = new Board();
    $postID = 61;
    $boardID = 1;
    $sBoard = $sB->savePostToBoard($postID, $boardID);
} catch (Exception $e) {
        $error = $e->getMessage();
}
}

这是表格:

<form method="post">
 <div class="btn-group" data-toggle="buttons">
<?php foreach($boards as $key) : ?>

 <label class="btn btn-primary active">
 <input type="radio" name="option[]"value="
  <?php echo $key['boardID'];?>">
  <?php echo $key['boardTitle']; ?></label>
  <?php endforeach ?>
  <input class="btn btn-danger"type="submit" value="Toevoegen" 
  id="addBoard" name="addBoard">
    </div>
</form>

类功能:

public function getConnection() {
    $conn = Db::getInstance();
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    return $conn;
}
private function getInputParameterDataType($value) {
$dataType = PDO::PARAM_STR;
if (is_int($value)) {
    $dataType = PDO::PARAM_INT;
} elseif (is_bool($value)) {
    $dataType = PDO::PARAM_BOOL;
}
return $dataType;
}
public function savePostToBoard($postID, $boardID)
{
$sql ="UPDATE board SET postID=:". $postID . " WHERE boardID=:boardID";
$statement = $this->getConnection()->prepare($sql);
$statement->bindValue(":boardID",$boardID, $this-
>getInputParameterDataType($boardID));
$statement->bindValue(":postID", $postid);
return $statement->execute();

}

非常感谢任何反馈,感谢您抽出宝贵时间。 亲切的问候

Database Layout Table Board

The FrontEnd with Form Database Layout Table Items

2 个答案:

答案 0 :(得分:0)

*)所有单选按钮都具有相同的id属性。它应该是独一无二的。

*)给id&#34; addBoard&#34;到提交按钮。

*)为什么使用POST和GET?

$boardID = $_POST['option'];
$postID = $_GET['id'];

*)你错过了statement->bindValue(":boardID",boardID);中的$符号!

*)发布数据类型应对应于db数据类型。使用bindValue()中的第三个参数来定义相应的数据类型。并使用一个函数:

private function getInputParameterDataType($value) {
    $dataType = PDO::PARAM_STR;
    if (is_int($value)) {
        $dataType = PDO::PARAM_INT;
    } elseif (is_bool($value)) {
        $dataType = PDO::PARAM_BOOL;
    }
    return $dataType;
}

然后这样打电话:

$statement->bindValue(":boardID",$boardID, $this->getInputParameterDataType($boardID));

*)PDO :: prepare()可以抛出PDOException或值FALSE。所以你应该处理这两种情况。我写了一个关于这个的答案:My answer用于prepare()&amp;的异常处理。执行()。

*)你到现在为止做了一些改变吗?什么工作,或者还没有?

好的,我现在就研究它。

新代码的解决方案:

*)不要使用分号&#34;;&#34;在sql语句的末尾。

*)更新应具有以下形式:

UPDATE [table-name] SET [col1]=:[col1],[col2]=:[col2] WHERE [PK-name]=:[PK-name]

*)为了便于阅读:在变量中传递sql语句并使用点来分隔其中使用的变量。像:

$sql = "UPDATE board SET postID=:" . $postid . " WHERE boardID=:boardID"
$statement = $conn->prepare($sql);

*)正如@teresko提醒您:您没有将$boardID传递给savePostToBoard()

$sBoard = $sB->savePostToBoard($postID, $boardID);
public function savePostToBoard($postID, $boardID) {...}

*)总体使用$postID$postid。现在你正在使用这两种形式。做出选择。

现在应该可以了。让我知道。

一些建议:

*)让你的方法只做一件事(如果可能的话)。在您的问题中,连接创建不属于该方法。如果调用20个需要连接的方法,则必须在每个方法中编写相同的连接创建代码。在您的情况下,最好在getConnection()类中定义Board方法。

public function getConnection() {
    $conn = Db::getInstance();
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    return $conn;
}

现在,您只需通过调用savePostOnBoard()即可获得此内容:

public function savePostToBoard($postID) {
    $statement = $this->getConnection()->prepare(...);
    //...
}

*)通常,使用构造函数传递方法稍后使用的变量会更好。这是构造函数的作用:初始化,例如在创建时为对象属性提供初始值。例如:

class Auto {

    private $color;
    private $doors;
    private $airConditioning;

    public __function __construct($color = 'blue', $doors = 3, $airConditioning = true) {
        $this->color = $color;
        $this->doors = $doors;
        $this->airConditioning = $airConditioning;
    }
}

$myAuto = new Auto('red', 4, false);
$hisAuto = new Auto('yellow', 8, true);

哦,并且总是给变量,函数,类等提供易于理解的名称。在您的情况下,上面的短语和这一个将适用,例如,像这样:

$board = new Board($boardID);
$boardUpdated = $board->update($postID);

请参阅?更好的名字,更符合逻辑(遵循我们现实世界的看法)的论点安排。

*)我还建议您在方法中拆分代码。通过这种方式,您可以获得更好的代码片段可重用性以及优雅,易于理解的结构。也许这类似于你的代码:

public function savePostToBoard($postID, $boardID) {
    $sql = "UPDATE board SET postID=:" . $postID . " WHERE boardID=:boardID";
    $bindings = array(
        ':postID' => $postID,
        ':boardID' => $boardID
    );
    $statement = $this->execute($sql, $bindings);
    return $statement->rowCount();
}

protected function execute($sql, array $bindings = array()) {
    $statement = $this->prepareStatement($sql);
    $this->bindInputParameters($statement, $bindings);
    $this->executePreparedStatement($statement);
    return $statement;
}

private function prepareStatement($sql) {
    $statement = $this->getConnection()->prepare($sql);
    return $statement;
}

private function bindInputParameters($statement, $bindings) {
    foreach ($bindings as $key => $value) {
        $statement->bindValue(
                $this->getInputParameterName($key)
                , $value
                , $this->getInputParameterDataType($value)
        );
    }
    return $this;
}

private function getInputParameterName($key) {
    if (is_int($key)) {
        return $key + 1;
    }
    $trimmed = ltrim($key, ':');
    return ':' . $trimmed;
}

private function getInputParameterDataType($value) {
    $dataType = PDO::PARAM_STR;
    if (is_int($value)) {
        $dataType = PDO::PARAM_INT;
    } elseif (is_bool($value)) {
        $dataType = PDO::PARAM_BOOL;
    }
    return $dataType;
}

private function executePreparedStatement($statement) {
    $statement->execute();
    return $this;
}

祝你的项目好运!

答案 1 :(得分:-1)

你真的应该在你的PDO实例中使用它们:

 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

然后你会在查询中看到语法错误:
出于某种原因,你有VALUES (:postID;)(注意分号)。

此外,您实际上并未在任何时候将$boardID传递给savePostToBoard()方法。您应该在该方法中添加第二个参数。

至于你的一般应用程序结构,你真的应该避免使用单例来共享数据库连接,你应该将域逻辑与持久性逻辑分开。阅读this post可能对您有益。