Laravel distincted script mechanics call - php

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.

Related

Symfony 3 Ajax call routing issue

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.

How can I create a PHP Kohana application with restful webservices?

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.

Using Symfony to get post data sent by Backbonejs

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

How to organize server side ajax scripts

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 ), ...."

PHP OOP and AJAX: How to handle serverside in Class?

I'm working on converting my standard PHP project to OOP but I ran into a wall about how to handle AJAX calls with PHP Classes. I'm not happy with the way I'm doing this now. I have a TillAjax.php file which I call from my TillUI.php file from a AJAX call.
In the TillAjax.php file I do this to get the information passed from the ajax call.
$till = new Till();
if(isset($_POST['data']))
$till->doStuff($_POST['data']);
I think this ruins the OOP.
I have worked with ASP.NET MVC and here its possible to call a specific action in a controller without i have to check for the post value. So I want to know if there is a smarter PHP way to solve the above problem?
The method I use for this is to have an Ajax class.
Your php file calls Ajax::Process($_GET['handle']), where 'handle' contains the name of a static class method, so perhaps 'Till::Process'. The Ajax class checks the function against a list of permitted functions (i.e. functions that you are allowing to be called via ajax), and then uses call_user_func_array to call the function (my code uses the contents of $_POST as arguments to pass to the function). The return of that function is automatically encoded as json and outputted to the client.
This means that your target php file looks like this:
<?php
//File: ajax.php
include ("Ajax.php");
Ajax::Process($_GET['handle']);
?>
Which I think is pretty simple.
Then you can have javascript that looks like this (jquery) :
$.get('ajax.php?handle=Till::Process', {}, function(result) {
//called on page response
});
So then result now contains whatever data is returned from the php method Till::Process.
Have you considered using a PHP MVC framework such as CodeIgniter, CakePHP, Kohana, etc? They will let you route requests to specific controller methods. It will be a much cleaner solution if migrating to one of these frameworks is an option for you.

Categories