Why can't I connect to database using PHP Slim framework? - php

I'm new to PHP Slim framework and I've written code to connect to database but it shows the following error in console (The database exists, still getting error):
Here's my code:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';
function dbConnect(){
$host='127.0.0.1';
$user='root';
$pass='';
$dbname='testdbmysql';
$pdo= new PDO("mysql:host=$host; dbname= $dbname", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $pdo;
}
$app = new \Slim\App;
$app->post('/hello/{id}', function (Request $request, Response $response, $args) {
echo "hello";
$names = $request->getParsedBody();
$db=dbConnect();
$names_arr=[];
$names_arr['name1']= filter_var($names['name1'], FILTER_SANITIZE_STRING);
$names_arr['name2']= filter_var($names['name2'], FILTER_SANITIZE_STRING);
$response->getBody()->write("Hello , ".$names_arr['name1']);
$query=mysqli_prepare($db, "INSERT into info(fname, lname) VALUES(?, ?)");
mysqli_stmt_bind_param($query, "ss", $names_arr['name1'], $names_arr['name2']);
$result=mysqli_stmt_execute($query);
$rows=mysqli_stmt_insert_id($query);
echo "Rows: ".$rows;
return $response;
});
$app->run();
?>
When I searched on Internet, I found solutions to same error caused by Laravel framework, but not about Slim. Is there something I can do?

You should remove the whitespace
$pdo= new PDO("mysql:host=$host; dbname=$dbname", $user, $pass);
The error output is displaying the whitespace, too. So that should be the mistake.
Also, do not Mix up PDO and mysqli. You are passing a PDO-Connection to mqsqli functions, thats why you get " Expected mysqli, got PDO."
I would stick with mysqli and set up a connection via mysqli_connect().

Related

Endpoint can't make a POST request properly in PHP using SLIM framework

I'm trying to make a API server that is supposed to connect to a data base, using SLIM framework following this tutorial. Actually I made a endpoint who get data from the data base, but can't insert new one.
Every time when I try to insert new data the POST parameters are nulls and the data base only send a error message.
In my groupes.php I have the following:
<?php
use Slim\Http\Request;
use Slim\Http\Response;
// Routes
$app->get('/[{name}]', function (Request $request, Response $response, array$args) {
// Sample log message
$this->logger->info("Slim-Skeleton '/' route");
// Render index view
return $this->renderer->render($response, 'index.phtml', $args);
});
$app->group('/api', function () use ($app) {
$app->group('/v1', function () use ($app) {
$app->get('/clients', 'getClients');
$app->post('/make', 'addClient');
});
});
The code above is just to define two endpoits: getClients and addClient.
And in my index.php I have:
function getConnection(){
$dbhost = "127.0.0.1";
$dbuser = "root";
$dbpass = "dzpga883yRusPHhv";
$dbname = "pruebaandroid";
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
//method: GET
//domain: mi-api/api/v1/clients
function getClients($response){
$sql = "SELECT * FROM cliente";
try{
$stmt = getConnection()->query($sql);
$client = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
return json_encode($client);
}
catch(PDOException $e){
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
//method: POST
//domain: mi-api/api/v1/make
function addClient($request) {
$client = json_decode($request->getBody());
$sql = 'INSERT INTO cliente (nombre, apellido, cedula, direccion, telefono, email) VALUES (:nombre, :apellido, :cedula, :direccion, :telefono, :email)';
try {
$db = getConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam(":nombre", $client->nombre);
$stmt->bindParam(":apellido", $client->apellido);
$stmt->bindParam(":cedula", $client->cedula);
$stmt->bindParam(":direccion", $client->direccion);
$stmt->bindParam(":telefono", $client->telefono);
$stmt->bindParam(":email", $client->email);
$stmt->execute();
$client->id = $db->lastInsertId();
$db = null;
echo json_encode($client);
}
catch(PDOException $e){
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
So, using postman to do a GET request to mi-api/api/v1/clientes retrieve all the data as spected, but whhen I try with a POST request mi-api/api/v1/make?nombre=asdf&apellido=asdf&cedula=asdf&direccion=asdf&telefono=asdf&email=asdf it's supposed to insert the new information but postman give me the following error:
{"error":{"text":SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'nombre' cannot be null}}
Looks like the addClient function it's not geting the parameters, so it's taking it as null. Why is this happening? I don't know what is wrong here, any response is welcome.
See the image
PD: yes, the DB is well formated, it have a id as PK auto increment and I tryed to print echo client->nombre and prints nothing but the error.
You are adding your parameters as GET parameters (added on url).
Use the BODY -> form-data tab to specify your POST parameters (The same you have in PARAMS tab)

PHP REST API query returning empty body

I cannot get my PHP Rest API to work, it is just returning empty body
with a successful HTTP request(200).
When I just echo something out it returns it fine. I am using Slim (PHP micro framework), MySQL,apache. Database table is created in phpmyadmin.
index.php
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';
require '../src/config/db.php';
$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response) {
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
return $response;
});
// Customer Routes
require '../src/routes/dates.php';
$app->run();
db.php it also contains dbhost, dbuser, dbpass and dbname
variables above
<?php
class db
{
// Properties
var $dbhost = 'localhost';
var $dbuser = 'root';
var $dbpass = 'parool1';
var $dbname = 'slimapp';
// Connect
public function connect()
{
$mysql_connect_str = "mysql:host=$this->dbhost;dbname=$this->dbname";
$dbConnection = new PDO($mysql_connect_str, $this->dbuser, $this->dbpass);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbConnection;
}
}
dates.php
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
$app = new \Slim\App;
// Get All Calendar Dates
$app->get('/api/date', function (Request $request, Response $response) {
$sql = "SELECT * FROM `calendardates`";
try {
// Get DB Object
$db = new db();
// Connect
$db = $db->connect();
$stmt = $db->query($sql);
$dates = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($dates);
} catch (PDOException $e) {
echo '{"error": {"text": ' . $e->getMessage() . '}';
}
});
Solution:
Change collation of database table to utf8 (if you want to use charcaters like "ö, ä, ü" in your database table).
I changed
$dbConnection = new PDO($mysql_connect_str, $this->dbuser, $this->dbpass);
to
$dbConnection = new PDO($mysql_connect_str, $this->dbuser, $this->dbpass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
to fix the problem.
To return a json try to replace
echo json_encode($dates);
With
return $response->withJson($dates);
As suggested by mim in comment.

Slim Framework - PDO object created but seems not inside the scope

I get this error when I try to test my codes.
Call to a member function prepare() on a non-object in ........
Below is my codes :
ConnectionStrings.php
<?php
$config = require dirname(__FILE__).'../../Configs/Local.php';
$host = '127.0.0.1';
$db = 'CWW_SecurityDB';
$user = $config['db']['user'];
$pass = $config['db']['password'];
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $user, $pass, $opt);
?>
Authentication.php (Related part)
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require dirname(__FILE__).'../../../ConnectionStrings.php';
$app -> group('/authentication', function(){
$this -> Get('/login',
function($request, $response, $args)
{
$Username = $request->getQueryParams()['Username'];
$Password = $request->getQueryParams()['Password'];
$sql = 'CALL SEC.usp_GetSecurityUsers(:Username)';
$stmt = $pdo -> prepare($sql);
$stmt -> bindParam(':Username', $Username, PDO::PARAM_STR);
$stmt -> execute();
.
.
. (just a try out on the codes)
The problem should lie in the line $stmt = $pdo -> prepare($sql);. However, I really could not figure it out after hours. I have read some other posts with similar issue suggesting that the $pdo is out of scope.. but how exactly is my $pdo out of scope in this case? Can someone please enlighten me. Thank you in advance guys :)
In PHP, you don't have global variables automatically available in the function scope (more on variable scope). Inside the function, $pdo needs to either be defined or somehow made available. Few ways come to my mind:
Using global $pdo; in the function start - very old-school and won't be generally preferred way by php professionals.
Replacing $pdo with $GLOBALS['pdo'] - pretty much the same thing, kind of PHP3 style :)
Pass $pdo to the closure's scope:
$app->group('/authentication', function() use ($pdo) {
$this->Get('/login', function($request, $response, $args) use ($pdo) {
Fetch $pdo through dependency container (Slim3 uses Pimple for that):
// Store $pdo in DI container.
$container = $app->getContainer();
$container['database'] = $pdo;
...
// Then inside route controller:
$pdo = $this->get('database');

How to run simple Php API?

I used Php Slim Framework for my API. I install the Slim Framework to my web root directory on my server and copy the index.php file I coded.
Index.php:
<?php
require 'vendor/autoload.php';
$app = new \Slim\Slim();
$app->contentType('application/json');
$app->get('/users', 'getUsers');
$app->get('/user/:id', 'getUser');
$app->run();
function getConnection() {
$dbhost="localhost";
$dbuser="";
$dbpass="";
$dbname="";
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
function getUsers() {
$sql = "select * FROM manga";
try {
$db = getConnection();
$stmt = $db->query($sql);
$users = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($users);
}
catch(PDOException $e) {
echo json_encode($e->getMessage());
}
}
?>
I am getting 500 (Internal Server Error).
Edit: I changed "$app = new Slim();" to the "$app = new \Slim\Slim();" then receive the below error.
I am using EasyEngine(Nginx).
Edit-2:Now 500 Internal gone but another error showing.
XMLHttpRequest cannot load http://api.mangayurdu.com/users. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://deneme.mangayurdu.com' is therefore not allowed access.
Here is my code that getting JSON data:
.factory('MY', function($http){
var factory = {};
var url = 'http://api.mangayurdu.com/users?callback=JSON_CALLBACK';
factory.isimler = $http.get(url);
return factory;
})
From the posted code it looks like Slim can't find a function called getUser. getUsers() is defined in your code, but no getUser() function.
try putting this in the start of your PHP page
<?php header('Access-Control-Allow-Origin: *');?>

How to connect with SLIM REST api with MS SQL server?

I am trying to get results from an API call using Slim connecting with MSSQLSERVER2012
the example used to work with MYSQL getconnection function (see below) but when I am trying to
connect with MsSQL server 2012 I am getting an error like "api call error "invalid data source name"
http://localhost/msapi/api.php/clients
1'api call error "invalid data source name"
require '/Slim/Slim.php';
$app = new Slim();
$app->get('/clients', 'getClients');
$app->run();
function getClients() {
$sql = "select * FROM clients";
try {
$db = getConnection();
$stmt = $db->query($sql);
$clients = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo '{"client": ' . json_encode($clients) . '}';
} catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
function getConnection_MYSQL() {
$dbhost="SERVER";
$dbuser="USER";
$dbpass="PASSWORD";
$dbname="DB";
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
function getConnection() {
$dbhost="SERVER";
$dbuser="USER";
$dbpass="PASSWORD";
$dbname="DB";
$dbh = new PDO ("ADODB.Connection");
$connStr = "PROVIDER=SQLOLEDB;SERVER=".$dbhost.";UID=".$dbuser.";PWD=".$dbpass.";DATABASE=".$dbname;
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->open($connStr); //Open the connection to the database
return $dbh;
}
the function getConnection_MYSQL() is an example that works.
But the getConnection() tryis to connect with MS SQL server ?
Do you see why I am getting an "invalid data source name" with the function getConnection()?
Since you didn't post an alternative DSN-string, I'm assuming you are using the one from your example and just replace host, username and password. This won't work.
When you are running your Slim-application on a windows host you can (and should) use Microsoft's SQL Server Driver for PHP (sqlsrv).
There are 2 versions sqlsrv.dll and pdo_sqlsrv.dll. When you want to reuse most of your code you should use the latter. This way you probably only have to modify your DSN (see php docs):
new PDO("sqlsrv:Server=localhost;Database=testdb", "UserName", "Password");
If you are using the first you have to update the way you connect to the db and create the query. You can read the Beginner's Guide to see a few examples that should make it easy.
If you are running not running your application on a Windows-machine you will probably have to set up ODBC and FreeTDS and then use PDO with an ODBC-DSN. From my experience this will be quite a lot of work, but there are a few good tutorials out there. Just google for "freetds sql server".

Categories