1

I am working with PHP slim framework to develop API. I can GET and DELETE but with the inserting (POST) and updating (PUT), I am facing problems.

    class db {
        //Propertise
        private $dbhost = 'localhost';
        private $dbuser = 'root';
        private $dbpass = '';
        private $dbname = 'bralivnara-api';
        //Connect
        public function connect(){
            try {
                $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', 'CHARSET utf8');
                $dbConnection = new PDO("mysql:host=$this->dbhost;dbname=$this->dbname;", $this->dbuser, $this->dbpass, $options);
                // set the PDO error mode to exception
                $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                //echo "Connected successfully"; 
            }
            catch(PDOException $e)
            {
                echo "Connection failed: " . $e->getMessage();
            }
            return $dbConnection;

 }
}

When I use rest easy I receive the 500 error.

Response Status: 500 (Internal Server Error)

When I passed the URL and press enter in browser, it shows the error

Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 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 'add' at line 1

Before I had an issue with Swedish letters also, it was not displaying in browser correctly. If anyone has same issue you can fix this issue with that header. It will work for all non-English letters

return $response->withStatus(200)
->withHeader('Content-Type', 'application/json;charset=utf-8;')
->write(json_encode($tranasVcDatainsamling, JSON_UNESCAPED_UNICODE));

If you want to see complete get code you can join our discussion.

Now the last problem which still remains is inserting to database. Here is the code for insertion to the database.

$app->post('/api/tranas-vc/add', function (Request $request, Response $response){
    $besöksdatum = $request->getParam('besöksdatum');
    $kön = $request->getParam('kön');
    $ålder_år = $request->getParam('ålder_år');
    $sökorsak = $request->getParam('sökorsak');
    $vp_objektiv_prio = $request->getParam('vp_objektiv_prio');
    $vp_objektiv_variabel_med_högst_prio = $request->getParam('vp_objektiv_variabel_med_högst_prio');
    $vp_mätning_prio = $request->getParam('vp_mätning_prio');
    $vp_mätning_variabel_med_högst_prio = $request->getParam('vp_mätning_variabel_med_högst_prio');
    $ess_val = $request->getParam('ess_val');
    $prio_ess = $request->getParam('prio_ess ');
    $prio_total = $request->getParam('prio-total');
    $utskrivning_hänvisning_återbesök = $request->getParam('utskrivning_hänvisning_återbesök');
    $åtgärd_remiss = $request->getParam('åtgärd_remiss');
    $om_lab_vilka_prover = $request->getParam('om-lab-vilka-prover');

    $sql = "INSERT INTO 
    `tranasvcdatainsamling`
    (
        `besöksdatum`,
        `kön`,
        `ålder_år`,
        `sökorsak`,
        `vp_objektiv_prio`,
        `vp_objektiv_variabel_med_högst_prio`,
        `vp_mätning_prio`,
        `vp_mätning_variabel_med_högst_prio`,
        `ess_val`,
        `prio_ess`,
        `prio_total`,
        `utskrivning_hänvisning_återbesök`,
        `åtgärd_remiss`,
        `om_lab_vilka_prover`
    )
     VALUES
    (
        :`besöksdatum`,
        :`kön`,
        :`ålder_år`,
        :`sökorsak`,
        :`vp_objektiv_prio`,
        :`vp_objektiv_variabel_med_högst_prio`,
        :`vp_mätning_prio`,
        :`vp_mätning_variabel_med_högst_prio`,
        :`ess_val`,
        :`prio_ess`,
        :`prio_total`,
        :`utskrivning_hänvisning_återbesök`,
        :`åtgärd_remiss`,
        :`om_lab_vilka_prover`
    )";
    try {
        // Get DB Objects
        $db = new db();
        // Connect
        $db = $db->connect();
        // Execute Query
        $stmt = $db->prepare($sql);
        $stmt->bindParam(':besöksdatum', $besöksdatum);
        $stmt->bindParam(':kön', $kön);
        $stmt->bindParam(':ålder_år', $ålder_år);
        $stmt->bindParam(':sökorsak', $sökorsak);
        $stmt->bindParam(':vp_objektiv_prio', $vp_objektiv_prio);
        $stmt->bindParam(':vp_objektiv_variabel_med_högst_prio', $vp_objektiv_variabel_med_högst_prio);
        $stmt->bindParam(':vp_mätning_prio', $vp_mätning_prio);
        $stmt->bindParam(':vp_mätning_variabel_med_högst_prio', $vp_mätning_variabel_med_högst_prio);
        $stmt->bindParam(':ess_val', $ess_val);
        $stmt->bindParam(':prio_ess', $prio_ess);
        $stmt->bindParam(':prio_total', $prio_total);
        $stmt->bindParam(':utskrivning_hänvisning_återbesök', $utskrivning_hänvisning_återbesök);
        $stmt->bindParam(':åtgärd_remiss', $åtgärd_remiss);
        $stmt->bindParam(':om_lab_vilka_prover', $om_lab_vilka_prover);
        $stmt->execute();
        echo '{"notice": {"text": "Tranås VC Entry Added"}';
    } catch(PDOEception $e) {
        echo '{"error": {"text": '.$e->getMessage().'}';
    }
});

We did all possible experiments on that code, you can see those suggestions in comments, but we still had the problem in POST and PUT.

I commented the $stmt->execute(); to stop the execution of the query and check, I got 200 success in rest easy, but data was not inserted. I browser the error was same. It shows that the problem is in execution. I checked that code on English letters kind of data, and it was working.

I am quite sure that I had the problem because of Swedish letter, which is non-English.

I database those columns which contain Swedish letters look like that

kön varchar(125)    latin1_swedish_ci   
sökorsak    varchar(125)    latin1_swedish_ci

Which show latin1_swedish_ci, that I want you to consider also. I will appreciate your help, and please join this discussion. If we fix this issue it will be very good research for non-English letters issue. I google almost whole day but did not got solution.

ZiaUllahZia
  • 1,072
  • 2
  • 16
  • 30
  • Not sure how php/mysql handles characters like that, can we see the error you received please? – IsThisJavascript Oct 17 '17 at 10:17
  • @ziaullahzia Use a database with encoding UTF8 general ci, you can add all languages. Using utf8_encode utf8_decode. Regards. http://php.net/manual/en/function.utf8-encode.php https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci –  Oct 17 '17 at 10:18
  • You should avoid having POST parameters in anything that are not ascii. And the same with the fields in the table. You can insert _data_ that are non-ascii just fine, but the constructs should follow a more strict pattern. – OptimusCrime Oct 17 '17 at 10:18
  • 3
    what does your `error_log` say caused the 500? – delboy1978uk Oct 17 '17 at 10:19
  • 1
    any log error as @delboy1978uk said, any from MYSQL PHP Apaches or Ngix ... –  Oct 17 '17 at 10:24
  • Thank you WillParky: The error look like that. Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 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 'add' at line 1 – ZiaUllahZia Oct 17 '17 at 10:54
  • So @ziaullahzia, you probably don't have access to DB rather than syntax error. Either wrong username, password or just no permission to insert or update. Check those out. – wast Oct 17 '17 at 10:56
  • @delboy1978uk when I insert via rest easy it says Internet 500 server error while in PHP is said syntax error – ZiaUllahZia Oct 17 '17 at 10:57
  • ok the syntax error, go to the line, there will be a semicolon missing or something stupid the line before it – delboy1978uk Oct 17 '17 at 10:59
  • @wast 49. I am using the same database connection for getting data, and it work. both for GET and DELETE but same error for POST and PUT – ZiaUllahZia Oct 17 '17 at 10:59
  • Then check if you have permissions to INSERT and UPDATE on those tables with SHOW GRANTS – wast Oct 17 '17 at 11:01
  • @delboy1978uk the error look like that.. when I past url /add and press enter. Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 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 'add' at line 1 I search on internet and this because of Swedish Letter, I think but I can not solve this. – ZiaUllahZia Oct 17 '17 at 11:02
  • There was also problem to get those letter then I add the header like: return $response->withStatus(200) ->withHeader('Content-Type', 'application/json;charset=utf-8;') ->write(json_encode($tranasvcdatainsamlings, JSON_UNESCAPED_UNICODE)); – ZiaUllahZia Oct 17 '17 at 11:03
  • @wast I can execute insert query via SQL. It means I have permission. – ZiaUllahZia Oct 17 '17 at 11:05
  • "for the right syntax to use near 'add' at line 1". Where is that 'add' in your query? – wast Oct 17 '17 at 11:05
  • @wast it is in the /api/tranas-vc/add (URL).. I replace that but still showing this. Confusing for me. – ZiaUllahZia Oct 17 '17 at 11:07
  • @ headmax I will check that also – ZiaUllahZia Oct 17 '17 at 11:08
  • Yeah, very confusing that SQL error doesn't give back part of SQL. – wast Oct 17 '17 at 11:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156908/discussion-between-wast-and-ziaullahzia). – wast Oct 17 '17 at 11:11
  • Why isn't your code in english? – tereško Oct 17 '17 at 18:26
  • @tereško this is requirements to use Swedish. – ZiaUllahZia Oct 17 '17 at 19:06
  • @ziaullahzia in the code itself? Like for query placeholders and parameter names? That's insane. You might want to start looking at other job opportunities. As for the solution, the charset should be part of the DSN, see here: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers#Connecting_to_MySQL – tereško Oct 17 '17 at 19:54
  • Ok, you mean I will change variables to English and it will work? can you please explain what I can change in the code – ZiaUllahZia Oct 17 '17 at 21:07
  • @ tereško I change all Swedish word from the code, and in database columns. I am inserting Swedish but still the same error – ZiaUllahZia Oct 17 '17 at 21:47

1 Answers1

1

You already use SET NAMES which is the right approach, but you need to wrap the utf8 inside a single quotation mark, as defined in the MySQL documentation

SET NAMES 'charset_name' [COLLATE 'collation_name']

$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'", 'CHARSET utf8');
                                                            ^    ^
jmattheis
  • 10,494
  • 11
  • 46
  • 58