I am very very new to PHP and Kohana. Already created a sample/demo "hello World" PHP Kohana application which is running sucessfully in WAMP server.
I want my application to be work as a complete server side component.
Since i'll have only server side logic in this application, it should use a ORM to communicate with my MySQL database.
I'll have a separate client side application which will have UI parts.
So I want my PHP-Kohana should recognize the RestFul webservices call from my client and give the JSON response accordingly.
Is it possible to create a Kohana application which supports RestFul webservices?
If yes, give me a guidance to create the webservices in Kohana application.
Is there any such sample code for demo?
There is no specific demo or sample code that I know of, so hopefully these tips will help to get you started with it...
It is possible, and relatively easy, to accept AJAX requests and produce JSON responses with Kohana. The first thing to be aware of is that unless told otherwise, Kohana will always try to generate the view, and this will fail as a JSON response so first things first:
if ($this->request->is_ajax()) {
// Disable any rendering of the template so it just returns json.
$this->auto_render = FALSE;
}
You'll probably want to put this in the before() method, probably of the parent Controller so that it always runs before you are getting data from the DB.
My personal preference for something like this would be to set up a standard AJAX response array so that the data is always returned in a relatively standard format. Example:
// Standard ajax response array.
$this->ajax_response = array(
'success' => FALSE,
'error' => NULL,
'raw_data' => NULL,
'generated' => ''
);
Customise the above to match your required usage. You'll probably also want this in your before() method.
Now in your action methods, get the data from the DB and add it to the array.
public function action_foobar() {
// Get the primary key ID from the URL.
$var1 = $this->request->param('var1');
$data = ORM::factory('Model', $var1);
if ($data->loaded()) {
$this->ajax_response['success'] = TRUE;
$this->ajax_response['raw_data'] = $data;
} else {
$this->ajax_response['error'] = 'Data could not be found.';
}
}
You should then be able to request this data by calling a URL such as http://www.website.com/controller/foobar/42
The final piece of the puzzle is actually returning this data, as at the moment Kohana won't output anything because we have told it not to. In your after() method, do the following:
if ($this->request->is_ajax()) {
$this->request->headers('Content-Type', 'application/json');
$this->response->body(json_encode($this->ajax_response));
}
Then you're free to interpret that response however you see fit in the jQuery on your client-side application:
$.ajax({
type: "POST",
url: "http://www.website.com/controller/foobar/" + foobarId,
dataType: 'json',
success: function (data) {
if (!data.success) {
alert(data.error);
} else {
// Handle the returned data.
}
},
error: function (xhr, status, errorThrown) {
// Something went very wrong (response failed completely).
alert(errorThrown);
}
});
Good luck with building your app! I hope this helps to at least get you started.
Related
I'm setting up a simple Ajax call in one of my forms. When a user enters characters in a field, the following Ajax call is activated:
self.modify = function (input_field) {
if ($(input_field).val().length > 5) {
$.post("{{path('get_bio_control_sample')}}", {sample_number: $(input_field).val()},
function (response) {
if (response.code == 100 && response.success) {
alert(response.sample_number);
}
}, "json");
}
};
Which is meant to access the following controller action:
class BioControlController extends Controller {
/**
* #Route("/bio_control/sample", name="get_bio_control_sample")
*/
public function getBioControlSampleAction(Request $request){
$sample_number = $request->query->get('sample_number');
$response = array("code" => 100, "success" => true, "sample_number" => $sample_number, "sample_data" => "test");
return new JsonResponse($response);
}
}
However, when the call is activated JS returns the error:
http://127.0.0.1:8000/omics_experiment/%7B%7Bpath('get_bio_control_sample')%7D%7D 404 (Not Found)
I'm accessing the Ajax call from omics_experiment/new (which is in the OmicsExperimentController) and using the route /bio_control/sample (as shown by the annotation), but it's not working. Can someone explain what I'm doing wrong?
I used this question as a template, the fact I'm using Symfony 3 might mean there are syntactic errors.
I just had to do this recently. I'm no expert on Symfony either, but since I just did this I may be able to help. Using Symfony is not really much different than doing it with a static URL. The main thing is to make sure that your controller and route are set up properly and working without AJAX, then you just need to use the path set in your route for the .post call.
And what makes it worse, is that it's really hard to test this type of interaction. Even your twig includes can cause it to fail if they are set up wrong.
Looking at your code again I think this may be the problem. Change this
$.post("{{path('get_bio_control_sample')}}", {sample_number:
to this
$.post("/bio_control/sample", {sample_number:
Because I think the way you have it is only good for twig templates, so if Symfony is not looking at your JQuery file like it does a twig template, then, it's not going to understand how to get the route.
I am totally new in AngularJS and I am using PHP as the server script.
I have a PHP class with connection() and getUsers() functions:
public function connect()
{
$this->connection = new PDO("mysql:host={$this->db_host};dbname={$this->db_name}", $this->db_user, $this->db_pass);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->connection;
}
public function getUsers()
{
this->connect = this->connect();
$sql = "SELECT * FROM login";
$stmt = this->connect->prepare($sql);
$stmt->execute();
$res = $stmt->fetchAll();
return json_encode($res);
}
I am stuck at the angular part. How to call a function inside a url using $http.get() ?
$http.get('/angular/conn.php')
.success(function(result)
{
$scope.user = result;
})
.error(function(data, status)
{
$log.log(status);
});
And another question on the side: when using angular with php their is no need to call the class and the function that we should use at the top of each html page ?
You have to understand how the client/server architecture works for Angular. Angular is built to work along a web service, which is responsible for providing among other things, database access. The way you communicate with a web service is through API calls often made with AJAX. You can't simply call a php method from an Angular app like you would from another php class/script. You would have to design a web service in php in order to communicate with it.
Since you are trying to access a resoutce using a GET method on '/angular/conn.php', then your PHP web service should have a way to parse requests and respond accordingly considering the HTTP method, resource name, HTTP headers, etc. Since Angular is meant to work along REST web services, I would recommend you to use a PHP framework that fits such purpose. For example: Slim Framework
Here are some references you might find useful:
What exactly is RESTful programming?
REST Web Services
well the examples i saw where using then when you use GET method for example:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http({
method : "GET",
url : "your url here"
}).then(function mySucces(response) {
$scope.myWelcome = response.data;
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
});
try to put your complete url like: localhost:8080/mypage.php
and print in console the result,
you can first make the request in the browser to check if the server is responding the request
I am pretty much beginner in programming. Since few weeks I've been using Laravel framework. So far, I was using ajax and redirects to reach the functions in controller through Routes. Someone told me that it is wrong to use redirects and so many ajaxes in Views. So how do I call these functions and all mechanics in a proper way then? I read the documentation not for the first time but I still dont get it. Could someone explain it to me a little bit please?
This is an example how do I use views with controller.
viewfile.blade.php:
$.ajax({
type: "POST",
url: "/ineedthisfunction",
data: {
},
success: function(msg) {
alert(msg);
},
error: function(error) {
alert('error');
}
});
routes:
Route::post('/ineedthisfunction', 'Controller#thisfunction');
controller:
public function thisfunction(){
return "some returned value from script";
}
I am doing this everytime I need to use any php code. Or I am writing it inside of views. They tell me both are wrong. What do I do then?
Sometimes instead of ajax i just do: "header("location:/ineedthisfunction"); But i think it is horrible idea to.
You mentioned redirects in your question, but I don't see any redirects in your controller method. In general, if you're going to make an AJAX call then sending a redirect response isn't going to do you any good. The browser itself isn't going to receive the redirect and navigate the user to the new page, your Javascript callbacks are going to be triggered with a status code of 301 (or 302, depending). Taken that way, redirecting in response to an AJAX request just doesn't make any sense.
You have a chance in your controller method to make a choice, however, on what to return. Is the request an AJAX request? Then return something. If not, then you can easily return your redirect:
use Illuminate\Http\Request;
// ...
public function thisFunction(Request $request)
{
if($request->wantsJson()) {
// Return data to ajax request
return response()->json(['key' => 'value']);
}
return redirect()->to('/some/url');
}
Without some more context of what you're trying to accomplish I'm afraid I can't be more specific.
I am new to backbone & symfony (as well as open source), and I am trying to make a sample application based on these 2 frameworks. I have an HTML page on front end (using backbone) which I send a request to backend system (using symfony) by calling model.save, model.destroy, etc. On backend system I have an action of a controller with the declaration as below:
public function createAction(Symfony\Component\HttpFoundation\Request $request)
but when I var_dump the $request I cannot find out the POST parameters that being sent from front end (neither $_REQUEST, $_POST).
I am wondering how could I get the POST parameter using Symfony?
Here is my code of Backbone
var BookModel = Backbone.Model.extend({
urlRoot : 'http://localhost/bookkeeper/web/app.php/',
defaults : {
title : '',
description : '',
pages : 0
}
});
var book = new BookModel();
var bookDetails = {
title : 'Test backbone test add new',
description : 'test add new',
pages : 354
};
book.urlRoot = 'http://localhost/bookkeeper/web/app_dev.php/create';
book.save(bookDetails, {
success : function(model, response) {
console.log(response);
},
error : function(model, response) {
console.log(response);
}
});
I also appreciate if you could provide me a tutorial to solve this.
Thank you for your help
PS: I could get the POST data if I use a HTML form by calling
$request->request->get('description')
You will want to make your way through the Symfony book which will help you with these questions and give you a fuller understanding of the way Symfony works rather than just cherry picking solutions from tutorials for your specific problem. Your questions will be answered by the chapter on the Controller and you may also want to look into Forms and Validation which will help with the processing and validation of the data coming in from Backbone / AJAX. All of the book is a great tutorial and should help you get started with the Symfony framework as a whole.
Sorry for the time try this
book.save(bookDetails, {
silent : false,
sync : true,
success : function(model, res) {
if (res && res.errors) {
console.log('no way, crap!');
} else {
console.log('yes i did it!');
}
},
error: function(model, res) {
console.log('error!');
}
);
You have to declare a Symfony Controller with an action that can handle an AJAX request. Inside your action, you can check if your Request object is AJAX or not via $request->isXmlHttpRequest().
For more you have to check Symfony documentation regarding controllers and the routing: http://symfony.com/doc/current/book/controller.html
Much of my work lately has involved expanding and bug fixing ajax actions. But the action lists are fairly unmanageable in size, and since I was not the original author and the comments are sparse, I spend a great deal of time tracing the code paths and trying to figure out which jquery event triggered the action and if it sent the proper data with the request.
Right now the ajax request scripts are basically just about a hundred if-else blocks split up into different files based loosely on their function.
Is there a relevant design pattern or a php idiom to help me better organize the php part of the ajax requests?
I was thinking of maybe making some sort of dispatch interface. (Don't know if it is a good or workable idea.) where I can register actions and somehow indicate what data they require. The dispatcher would then call the function from the appropriate place. Then I could route all ajax requests through a single script and organize my functions however I want. And I can have an overview of what data is required to call a certain action without reading its implementation line by line. I would potentially have access to my server-side class heirarchy from the client side.
Does this sound workable? Is this safe? Are there other ways that might work better? The inspiration for this was basically smalltalk style message passing. My major worry is that I am going to introduce a cross-side request forgery vulnerability or that there is already one present in the code and due to it being difficult to read, I missed it.
I use a RPC-style mechanism to achieve what I think you want.
Disclaimer: I've successfully implemented this scheme in JS+PHP and JS+Python, so it is workable. But it might not be secure. You have to take all appropriate verification steps to make sure it is secure (especially w.r.t. to code/SQL injection and XSS attacks)
The idea is to have a single PHP script that processes the RPC requests, receiving the method name and its argument through both GET and POST, and outputs JSON back to the Javascript side.
For instance, on the client side:
API.rpc('getItemById', 1532, function(item) { console.log(item); });
would write
Object(id=1532,name="foo",whatever="bar")
on the console.
The communication protocol I use is the following:
the client sends an HTTP request to the RPC handler script, using
either GET or POST. The restrictions are that the 'method' must
always be provided in the GET, and that all arguments must be
URL-encoded. Otherwise, all arguments are given as key=value pairs and can be part of the request (GET) or the payload (POST)
the server always responds with an HTTP 200 (otherwise it means that a very nasty thing happened). It responds only with JSON data. The returned object has at least 2 members.
the 'success' member is always there, and indicates if the call succeeded - i.e. that no exception was thrown
if successful, the 'ret' members contains the return value of the function
if an exception was thrown, the 'message' member contains the exception message (I prefer sending the whole backtrace here, but that's certainly not good for sensitive environments)
(1) On the javascript side (assuming jQuery, coding as I think, so this may be buggy):
API = function() {
this.rpc = function(method, args, callback) {
return $.ajax({
url: 'rpcscript.php?method='+encodeURIComponent(args.method),
data: args,
type: 'post', //only the method name is sent as a GET arg
dataType: 'json'
error: function() {
alert('HTTP error !'); // This is e.g. an HTTP 500, or 404
},
success: function(data) {
if (data.success) {
callback(data.ret);
} else {
alert('Server-side error:\n'+data.message);
}
},
});
}
}
You can then add shortcut functions such as syncRPC() to perform synchronous calls, etc.
(2) On the PHP side (slightly modified running code):
class MyAPI
{
function getItemById($id)
{
// Assuming the $db is a database connection returning e.g. an associative array with the result of the SQL query. Note the (int) typecast to secure the query - all defensive measures should be used as usual.
return $db->query("SELECT * FROM item WHERE id = ".(int)$id.";");
}
}
class RemoteProcedureCall
{
function __construct()
{
$this->api = new MyAPI();
}
function serve()
{
header("Content-Type: application/json; charset=utf-8");
try
{
if (!isset($_GET['method']))
throw new Exception("Invalid parameters");
$methodDesc = array($this->api, $_GET['method']);
if (!method_exists($methodDesc[0], $methodDesc[1]) || !is_callable($methodDesc))
throw new Exception("Invalid parameters");
$method = new ReflectionMethod($methodDesc[0], $methodDesc[1]);
$params = array();
foreach ($method->getParameters() as $param)
{
// The arguments of the method must be passed as $_POST, or $_GET
if (isset($_POST[$param->getName()]))
// OK, arg is in $_POST
$paramSrc = $_POST[$param->getName()];
elseif (!in_array($param->getName(),array('action','method'))
&& isset($_GET[$param->getName()])
&& !isset($paramSrc[$param->getName()]))
// 'action' and 'method' are reserved $_GET arguments. Arguments for the RPC method
// can be any other args in the query string, unless they are already in $_POST.
$paramSrc = $_GET[$param->getName()];
if (!isset($paramSrc))
{
// If the argument has a default value (as specified per the PHP declaration
// of the method), we allow the caller to use it - that is, not sending the
// corresponding parameter.
if ($param->isDefaultValueAvailable())
$p = $param->getDefaultValue();
else
throw new Exception("Invalid parameters");
}
else
{
$p = $paramSrc;
}
$params[$param->getName()] = $p;
unset($paramSrc);
}
$ret = $method->invokeArgs($db, $params);
echo json_encode(array('success' => true, 'ret' => $ret));
}
catch (Exception $e)
{
echo json_encode(array('success' => false, 'message' => $e->getMessage()."\n".$e->getBacktrace()));
}
}
};
$rpc = RemoteProcedureCall();
$rpc->serve();
There are many application-specific assumptions here, including the kind of exceptions that may be thrown, the reserved keywords, etc ...
Anyway I hope this provides a good starting point for your problem.
You can have a look here: http://www.phpapi.org/
From description:
"This is the skeleton upon which you can develop a web-system from a simple Web Calculator to the most sofisticated CRM/ERP/CMS/ETC. What PHP-API provides is: a general structure of the code, a very simple extendable API code structure,JavaScript connectivity with the API ( with an easy way of adding new modules/method handlers ), ...."