【解決方法】致命的なエラー: キャッチされていない mysqli_SQL_exception: SQL 構文にエラーがあります。 MariaDB サーバーのバージョンに対応するマニュアルを確認してください

プログラミングQA

[ad_1]

Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' , 2)' at line 1 in C:\xampp\htdocs\macibas_4p\formsKD\services\order_item_services.php:46 Stack trace: #0 C:\xampp\htdocs\macibas_4p\formsKD\services\order_item_services.php(46): mysqli->query('INSERT INTO ord...') #1 C:\xampp\htdocs\macibas_4p\formsKD\index.php(72): OrderItemServices->insertOrderItem('Juris Priede', '28741234', '23.11.2022', 'Razer pele 24.1...', '2') #2 {main} thrown in C:\xampp\htdocs\macibas_4p\formsKD\services\order_item_services.php on line 46
PHP挿入アクション
<pre><?php
                if(isset($_POST['add'])){
                    $orderData = $_POST['order'];
                    $productData = $_POST['product'];
                    
                    $fName = explode(" ", $orderData)[0];
                    $lName = explode(" ", $orderData)[1];
                    
                    $customer = $fName." ".$lName;
                    
                    $customerPhone = explode(" ", $orderData)[2];
                    $orderDate = explode(" ", $orderData)[3];
                    $qnt = $_POST['quantity'];
                    $p = $_POST['product'];
                    $product = explode(" ", $productData)[0];
                    
                    
                   	$result = $orderItemService->insertOrderItem($customer, $customerPhone, $orderDate, $p, $qnt);
                        
                    if($result){
                        echo "<p>Order item data insertion has been successful</p><br>";
                    }else{
                        echo "<p>Order item data insertion hasnt been successful</p><br>";
                    }
                
                }
            ?>
ServiceClassInsert
<pre>public function insertOrderItem($customer, $phone, $orderDate, $product, $quantity){
            if($customer == null || $phone == null || $orderDate == null || $product == null){
                return false;
            }
            
            $orderItems = $this->selectAllOrderItems();
            
            if(sizeof($orderItems) > 0){
               foreach($orderItems as $orderItem){
                   $customerName = $orderItem->getOrder()->getCustomer()->getName();
                   $customerPhone = $orderItem->getOrder()->getCustomer()->getPhone();
                   
                   $orderDateCheck = date_create($orderDate);
                   $orderDateCheck = date_format($orderDateCheck, 'd.m.Y');
                   
                   $isOrder = $customerName == $customer && 
                       $customerPhone == $phone &&
                       $orderDateCheck == $orderItem->getOrder()->getOrderDate();
                   
                   $productName = $orderItem->getProduct()->getName();
                   $isProduct = $productName == $product;
                   
                   if($isOrder && $isProduct){
                       return false;
                   }
               } 
            }
            
            $orderService = new OrderServices();
            $orderID = $orderService->selectOrderID($customer, $phone, $orderDate);
            
            $productService = new ProductServices();
            $productID = $productService->selectProductID($product);
            
            if($quantity == null)
                $quantity = 1;
            
            $sql = "INSERT INTO ".$this->table."(order_id, product_id, quantity) VALUES ($orderID, $productID, $quantity)";

            $isInserted = $this->conn->query($sql);

            if($isInserted){
                return true;
            }
            else{
                return false;
            }
        }

私が試したこと:

私は複数の異なることを試しました。 db への挿入に必要なデータを手動で挿入しようとし、それを var_dump に出力しようとしました。 オンラインで別の解決策を見ましたが、まだ何もありません。

解決策 1

そんなことしないで! 文字列を連結して SQL コマンドを作成しないでください。 データベース全体を破壊する可能性のある、偶発的または意図的な SQL インジェクション攻撃にさらされる可能性があります。 代わりに、常にパラメーター化されたクエリを使用してください。

文字列を連結すると、SQL が次のようなコマンドを受け取るため、問題が発生します。

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'

ユーザーが追加した引用符は、SQL に関する限り文字列を終了させ、問題が発生します。 しかし、それはもっと悪いかもしれません。 代わりに「x’;DROP TABLE MyTable;–」と入力すると、SQL は非常に異なるコマンドを受け取ります。

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'

どの SQL が 3 つの別個のコマンドとして認識されるか:

SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';

完全に有効な SELECT

SQL
DROP TABLE MyTable;

完全に有効な「テーブルの削除」コマンド

SQL
--'

そして、それ以外はすべてコメントです。
一致する行を選択し、DB からテーブルを削除し、それ以外は無視します。

したがって、常にパラメーター化されたクエリを使用してください。 または、DB をバックアップから頻繁に復元する準備をしてください。 バックアップは定期的に取っていますよね?

アプリ全体でそれを修正すると、目に見える問題が同時に消えます。

[ad_2]

コメント

タイトルとURLをコピーしました