This is the first time I am creating a restAPI. The API should only be able to process one request, which gives back all the data from an table. I went through this tutorial http://www.androidhive.info/2014/01/how-to-create-rest-api-for-android-app-using-php-slim-and-mysql-day-23/ for learning how to create an Rest API in PHP.
The Problem I am experiencing is that the api call returns an empty response and I have trouble figuring out where the error is. here the codes:
Index.php
<?php
/**
* Created by IntelliJ IDEA.
* User: Jakob Abfalter
* Date: 19.08.14
* Time: 14:17
*/
require_once '../include/DbHandler.php';
require '.././libs/Slim/Slim.php';
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();
/**
* Echoing json response to client
* #param String $status_code Http response code
* #param Int $response Json response
*/
function echoRespnse($status_code, $response) {
$app = \Slim\Slim::getInstance();
// Http response code
$app->status($status_code);
// setting response content type to json
$app->contentType('application/json');
echo json_encode($response);
}
/**
* Listing all foods
* method GET
* url /foods
*/
$app->get('/foods', function() {
$response = array();
$db = new DbHandler();
// fetching all foods
$result = $db->getAllFoods();
$response["error"] = false;
$response["foods"] = array();
// looping through result and preparing tasks array
while ($food = $result->fetch_assoc()) {
$tmp = array();
$tmp["id"] = $food["id"];
$tmp["name"] = $food["name"];
$tmp["img"] = $food["img"];
$tmp["description"] = $food["description"];
array_push($response["foods"], $tmp);
}
echoRespnse(200, $response);
});
$app->run();
?>
DbHandler.php
<?php
/**
* Created by IntelliJ IDEA.
* User: Jakob Abfalter
* Date: 19.08.14
* Time: 14:28
*/
class DbHandler
{
private $conn;
function __construct()
{
require_once dirname(__FILE__) . './DbConnect.php';
// opening db connection
$db = new DbConnect();
$this->conn = $db->connect();
}
/**
* Fetching all foods from database
*/
public function getAllFoods() {
$stmt = $this->conn->prepare("SELECT * FROM foods");
$stmt->execute();
$foods = $stmt->get_result();
$stmt->close();
return $foods;
}
}
DbConnect.php:
<?php
/**
* Created by IntelliJ IDEA.
* User: Jakob Abfalter
* Date: 19.08.14
* Time: 14:27
*/
class DbConnect {
private $conn;
function __construct() {
}
/**
* Establishing database connection
* #return database connection handler
*/
function connect() {
include_once dirname(__FILE__) . './Config.php';
// Connecting to mysql database
$this->conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check for database connection error
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// returing connection resource
return $this->conn;
}
}
?>
.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ %{ENV:BASE}index.php [QSA,L]
When I test the request in chrome advanced Rest Client it say:
I also tried already to put some echos in the function where the array is created and an echo in the Rspnse function, but both didnt show up
Oh actually I may have been wrong.
This looks like A problem if not THE problem.
Your method getAllFoods() closes the stmt handle $stmt->close();
You then pass the handle back to the calling code and attempt to process all the results using it.
You should not close the handle until you are finished processing the results from it.
I found the problem.
The line $foods = $stmt->get_result(); in the DbHandler threw an exception because the required driver mysqlidb wasn`t installed.
Related
I getting this is exception in my application, and don't understand why. This exception throw in for one collection, over collection not throw this exception, with processed insert(),update(), or delete()
/**
* insert to mongo db method
* #param $dataArray
* #param $collection
*/
static function insert($dataArray, $collection) {
$connect = Core_Model_Mongo::getConnect();
$write = new MongoDB\Driver\BulkWrite();
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY);
$write->insert($dataArray);
$connect->executeBulkWrite(
Config_Db::getConf()['mongodb']['db'].'.'.$collection,
$write,
$writeConcern
);
}
end get connect method
/**
* #return \MongoDB\Driver\Manager
*/
static function getConnect() {
if(!is_null(self::$_connect)) {
return self::$_connect;
}
self::$_connect = new \MongoDB\Driver\Manager(Config_Db::getConf()['mongodb']['connect']);
return self::$_connect;
}
data save in collection success full, and this exception not take insert(),update() and other methods. I temporary resolve this question by try catch block
try {
// my code
} catch(MongoDB\Driver\Exception\BulkWriteException $error) {
Core_App::log(var_export($error,true));
}
but this is resolve not correct because I need application without any exception,error,notice, and over log level error.
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: *');?>
Hi I am new to cassandra database. I am downloaded phpcassa from
https://github.com/mauritsl/php-cassandra.
When I tried to autoload cassandra library from application/config/autoload.php I got non existence class cassandra error.
Please help me to solve this issue.
o Place all Cassandra related files into application/library/ folder.
Remove the name space from each Cassandra class file.
"namespace Cassandra;"
Your file name and class name should match to load the library in auto load function in codeigniter.
Cassandra file class name is "Connection".
Change the class name as "Cassandra"
Your constructor expects a parameter to connect the database. You can't pass parameters while loading autoload library.
Change your constructor method name as connect
Using $this->cassandra->connect($host,$keyspace,$options) you can process the connection.
Rename the __construct into connect
/**
* Connect to Cassandra cluster.
*
* #param mixed $host
* Hostname as string or array of hostnames.
* #param string $keyspace
* #param array $options
*/
public function connect($host, $keyspace = NULL, $options = array()) {
$this->options += $options;
if (empty($host)) {
throw new InvalidArgumentException('Invalid host');
}
if (!is_array($host)) {
$host = array($host);
}
shuffle($host);
while ($host) {
$hostname = array_pop($host);
try {
$this->transport = new Transport($hostname, $this->options['connect_timeout'], $this->options['stream_timeout']);
break;
}
catch (Exception $e) {
if (empty($host)) {
// No other hosts available, rethrow exception.
throw $e;
}
}
}
Presently, I am trying to interface with a SOAP-based camera system to tie into its action API so I can control when its lights come on programatically and so forth. However, when I use the code below, it's saying it cannot bind to the service and doesn't seem to be able to properly digest the WSDL file associated with the API, which can be found here:
http://www.axis.com/vapix/ws/action1/ActionService.wsdl
Is there something that's wrong with my code, or is this an issue with the WSDL file itself? Thank you very much in advance for the assistance! In advance, the error generating is the following, generated at the instantiation of the SoapClient object in the constructor:
SOAP-ERROR: Parsing WSDL: Couldn't bind to service
<?php
/**
* The purpose of this class is to act as a means to interface with a Vapix camera
* using SOAP requests so that events may be broadcast to it.
*/
$vapix = new Vapix("http://www.axis.com/vapix/ws/action1/ActionService.wsdl",
"<http://camera.address.edu>",
"<username>", "<password>");
if ($vapix)
{
echo "Connection to VAPIX successful!\n";
}
else
{
echo "Connection to VAPIX unsuccessful!\n";
}
/**
* The constructor takes in a WSDL address, the actual interfacing address of the
* server we are connecting to, a username, and a password, and establishes the
* SOAP client we need to interface with said address.
*
* #param $wsdl The WSDL specification for the service we are interacting with.
* #param $address The actual server address we are interfacing with.
* #param $username The username we need to access the server.
* #param $password The password we need to access the server.
*
* #return New Vapix object ready to interface with SOAP service.
*/
class Vapix
{
// the soap client variable we will be using to store our Vapix connection
private $soapClient;
public function __construct($wsdl, $address, $username, $password)
{
try
{
$soapClient = new SoapClient($wsdl, array("soap_version" => SOAP_1_2));
}
catch (SoapFault $fault)
{
echo "Error instantiating SOAP object!\n";
echo $fault->getMessage() . "\n";
}
// prepare SOAP headers
$sh_param = array(
"username" => $username,
"password" => $password
);
$headers = new SoapHeader($address, "UserCredentials", $sh_param);
// prepare SOAP client
$soapClient->__setSoapHeaders(array($headers));
}
/**
* This function is a generalized function used for calling a SOAP request to
* whatever service or server we are linked up to (in this case a VAPIX camera)
* so that other more specialized functions can derive from it. It will take in
* the name of the function, as well as a list of parameters.
*
* #param $funcName The name of the function we want to call.
* #param $parameters The parameters for the function we want to call.
*
* #return $info Returns info from the call if successful, NULL otherwise.
*/
public function callSoapFunction($funcName, $parameters)
{
try
{
$info = $soapClient->__call($funcName, array($parameters));
}
catch (SoapFault $fault)
{
print(
"alert('Sorry, blah returned the following ERROR: " . $fault->faultcode . "-" .
$fault->faultstring.". We will now take you back to our home page.');
window.location = 'main.php';"
);
return NULL;
}
if ($error == 0)
{
return $info;
}
}
}
?>
At least the provided WSDL-file has no <service>-area at the end of the wsdl-definition right after the <binding> block. But this missing <service>-block is needed as it contains concrete servicespecific informations (for instance its webservice URL/endpoint is listed there).
I'm new to using SOAP and understanding the utmost basics of it.
I create a client resource/connection, I then run some queries in a loop and I'm done. The issue I am having is when I increase the iterations of the loop, ie: from 100 to 1000, it seems to run out of memory and drops an internal server error.
How could I possibly run either a) multiple simaltaneous connections or b) create a connection, 100 iterations, close connection, create connection.. etc.
"a)" looks to be the better option but I have no clue as to how to get it up and running whilst keeping memory (I assume opening and closing connections) at a minimum.
Thanks in advance!
index.php
<?php
// set loops to 0
$loops = 0;
// connection credentials and settings
$location = 'https://theconsole.com/';
$wsdl = $location.'?wsdl';
$username = 'user';
$password = 'pass';
// include the console and client classes
include "class_console.php";
include "class_client.php";
// create a client resource / connection
$client = new Client($location, $wsdl, $username, $password);
while ($loops <= 100)
{
$dostuff;
}
?>
class_console.php
<?php
class Console {
// the connection resource
private $connection = NULL;
/**
* When this object is instantiated a connection will be made to the console
*/
public function __construct($location, $wsdl, $username, $password, $proxyHost = NULL, $proxyPort = NULL) {
if(is_null($proxyHost) || is_null($proxyPort)) $connection = new SoapClient($wsdl, array('login' => $username, 'password' => $password));
else $connection = new SoapClient($wsdl, array('login' => $username, 'password' => $password, 'proxy_host' => $proxyHost, 'proxy_port' => $proxyPort));
$connection->__setLocation($location);
$this->connection = $connection;
return $this->connection;
}
/**
* Will print any type of data to screen, where supported by print_r
*
* #param $var - The data to print to screen
* #return $this->connection - The connection resource
**/
public function screen($var) {
print '<pre>';
print_r($var);
print '</pre>';
return $this->connection;
}
/**
* Returns a server / connection resource
*
* #return $this->connection - The connection resource
*/
public function srv() {
return $this->connection;
}
}
?>
Well, SOAP in PHP is a little problematic.
About your question: yes, SOAP accept simultaneous connections. You believe in a "out of memory". I believe that the major problem is around HTTP responses/per second.
Can you put here your apache error log ? - assuming that you uses PHP and Apache together in your environment.
Anyway, my advice for you is: use REST if you can !
Solved
It was a timeout issue.