Using Ajax to call PHP object method in the same file - php

I have a PHP file, .../datastuff.php
On this page a PHP object is instantiated. (The class is written in another file).
public class MyClass{
//....
public function doAfterClick(){
//.....
}
}
So in datastuff.php I do
$MyObject = new MyClass();
//user specific data is added to $MyObject
Now I want to call $MyObject->doAfterClick(), when the user presses a button on datastuff.php
I think AJAX is the general solution for this type of problem. But I am not sure how to do this?
If I wanted to call a PHP function written on another page I could use AJAX to POST data to that page. But I want to stay on this page, because MyObject needs to call the method.
If I POST back to datastuff.php won't $MyObject be lost?
If I make it a Singleton or Global would this then work?
I looked at this, which is a similar problem, ut is not quite what I am looking for:
Using JQuery ajax to call a PHP file, process, but stay on same page

Here's the basic idea:
# datastuff.php
// This object will be created upon each request
$MyObject = new MyClass();
$action = (array_key_exists('action', $_GET)) ? $_GET['action'] : '';
switch ($action) {
case 'do_something':
$response = $MyObject->doAfterClick();
// Output relevant feedback to the user or redirect them somewhere based on the response
// This was most likely called via AJAX, so perhaps output JSON data or
// some other means of communicating the response back to the javascript
break;
case 'do_something_else':
// etc...
break;
default:
// Present the information to the user...
break;
}
Your $MyObject will be created upon each request (i.e. on initial page load and after the button is clicked and fires an AJAX request) but it may be identical in each request assuming it has been given the same data. After the button is clicked, an ajax request to "datastuff.php?action=do_something" will make sure the relevant method is called.
Although something like this would work, it is not good code design. I'd recommend you spend some time researching MVC (Model, View, Controller) patterns.

Related

AJAX Call in MVC Structure PHP

I have an AJAX featured page with dynamic components. I was wondering about how to handle an ajax call in MVC.
The first idea I had was to create a new controller for ajax calls without rendering views and check in the routing for an ajax request like this
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
call_user_func_array(array("ajax", $this->url_action), null);
}
I would let the location of AJAX handling code depend on its context. If it is handling the same kind of content as another controller that returns a full view, just make an "ajax method" in that controller, that responds with for instance a JSON header, the contents you want to send to the browser and exits. Not really a need for a dedicated AJAX controller, just like you don't have a separate GET controller or POST controller.
EDIT: (an example)
class BookController
{
public function getBookDetail($id)
{
// Go fetch a book from the DB.
// Assemble your full fledged view
// Send it to the browser
}
public function ajaxBookDetail($id)
{
// Go fetch a book from the DB.
header('Content-Type: application/json');
echo json_encode($someBookData);
exit;
}
}
You can then tell your router to use the ajax-prefixed method instead of the get-prefixed one, if you detect xmlhttprequest in the SERVER headers.

Doing an Ajax GET request to return data to PHP

I want to make an Ajax search request agains an API and get the data returned to my PHP file, right now I'm using Javascript and jQuery to do the job. But I want to let PHP do all the job, simply because I don't want my API key to be public and I may want to cash the data in a database further on. It seems that it should be simple, but I just can't figure out how to do it clean, call javascript and return or how to "integrate" it with PHP.
I am doing my PHP in the MVC pattern, like so:
Controller called from "mastercontroller/index":
class SearchController {
public function DoControl($view, $model) {
$ret = "";
$ret .= $view->GetSearchForm();
if($view->TriedToSearch()) {
if($view->GetSearchString()) {
$ret .= $model->CheckSearchString($view->GetSearchString());
} else {
// Didn't search for anything
}
} else {
// Didn't press the search button
}
return $ret;
}
}
My view is returning an HTML form, checking if submit is pressed and also returning the searchstring, that I am sending in to my Model above.
Model:
class SearchModel {
public function CheckSearchString($searchString) {
// 1. Call Googlebooks api with the searchstring
// 2. Get JSON response to return to the controller
// 3. The controller sends the data to the View for rendering
}
}
I just can't figure out how I should do it.
I'm not entirely sure, but you seem to be asking how to perform an AJAX request without JavaScript. You can't do that -- it's not possible to use the XmlHttpRequest object without JavaScript. That's, according to legend, the origin of the "J" in the AJAX name.
It sounds like you need to use REST to call specific API's. RESTful state allows you to use web services to return specific data according to a predefined API. Data can be returned in XML or JSON.
You can do this very easily with PHP's cURL implementation using whatever keys Google gives you.
See Google's Google Books API Family page for links to PHP API and sample code.
Would the below practice be useful to you? If you just want to implement ajax functionality in your code.
Simple AJAX - PHP and Javascript
I am sorry for mistaking the content. How about the two below:
simple http request example in php
PHP HTTP-Request * from another stackoverflow question
But I think ajax is main in client program meaning. At the server-side, just call it http request.

How to handle AJAX request in my PHP MVC?

I am in the process of learning the MVC pattern and building my own lightweight one in PHP
Below is a basic example of what I have right now.
I am a little confused on how I should handle AJAX requests/responses though.
In my example user controller below, If I went to www.domain.com/user/friends/page-14 in the browser, it would create a User object and call the friends method of that object
The friends method would then get the data needed for the content portion of my page.
My app would load a template file with a header/footer and insert the content from the object above into the middle of the page.
Now here is where I am confused, if a request is made using AJAX then it will call a page that will do the process over, including loading the template file. IF an AJAX call is made, I think it should somehow, just return the body/content portion for my page and not build the header/footer stuff.
So in my MVC where should I build/load this template file which will have the header/footer stuff? ANd where should I detect if an AJAX request is made so I can avoid loading the template?
I hope I am making sense, I really need help in figuring out how to do this in my MVC I am building. IUf you can help, please use some sample code
/**
* Extend this class with your Controllers
* Reference to the model wrapper / loader functions via $this->model
* Reference to the view functions via $this->view
*/
abstract class Core_Controller {
protected $view;
protected $model;
function __construct(DependencyContainer $dependencyContainer){
$this->view = new Core_View();
//$this->view = $dependencyContainer->get(view);
}
public function load($model){
//load model
//this part under construction and un-tested
$this->$model = new $model;
}
}
user controller
/**
* Example Controller
*/
class User_Controller extends Core_Controller {
// domain.com/user/id-53463463
function profile($userId)
{
//GET data from a Model
$profileData = $this->model->getProfile($userId);
$this->view->load('userProfile', $profileData);
}
// domain.com/user/friends/page-14
function friends()
{
//GET data from a Model
$friendsData = $this->model->getFriends();
$this->view->load('userFriends', $friendsData);
}
}
For me, I developed a separate object that handles all template display methods. This is good because you can then ensure that all the resources you need to display your UI is contained in one object. It looks like you've isolated this in Core_View.
Then, when an AJAX call is made, simply detect that it is an AJAX call. This can be done by either making the AJAX call through an AJAX object, which then references other objects, or you can take an easy approach and simply set an extra POST or GET field which indicates an AJAX call.
Once you've detected if it's an AJAX call, define a constant in your MVC such as AJAX_REQUEST. Then, in your template/UI object, you can specify that if it's an AJAX call, only output your response text. If it isn't, proceed with including your template files.
For me, I send it through an AJAX object. That way I don't have to worry about making a single output work for both cases. When it's ready to send a response, I just do something to the manner of print( json_encode( ...[Response]... ) ).
well, it would all start with normal request which would load the initial page. there are many options as to handle this but let's say that you start with /users/friends page which would list all your friends. then each of the friends should have link to specific friend's profile -- now this is the moment where ajax could kick in and you could ajaxify links to your friend profiles - this means that instead of normal you would instead use let's say jQuery and setup click handler in a such way that
$("a").click(function(){$.post($(this).attr("href"), null, function(data){$("#content").html(data);}});
this would use "href", and upon click would make post request to your backend. at backend, if you see that it's post, then you would just return the content for that particular friend. alternatively, if you have get request, you return all - header - content - footer.
if you use technique above, make sure to properly handle the data you receive. e.g. if there are further actions that should be done via ajax, make sure to "ajaxify" the data you get back. e.g. after updating html of the content, again apply the $("a").click routine.
this is just trivial example, to kick you off, but there are many more sophisticated ways of doing that. if you have time, I suggest reading some of agiletoolkit.org, it has nice mvc + ajax support.
You will need to use a different view. Maybe something like:
funciton friends() {
$this->view = new Ajax_Request_View();
$friendsData = $this->model->getFriends();
$this->view->load($friendsData);
}

Difficulty using same PHP class when POSTing data from javascript and PHP contexts

I have a PHP class called FormController whose constructor currently validates some $_POST variables and throws an exception if they're not all set. The FormController should eventually return the address of the next page.
So my PHP page would something like:
session_start();
try {
// controller needs certain variables set in the $_POST
// superglobal to work properly.
$controller = new FormController();
echo $controller->nextPage();
} catch(Exception e) {
// Handle exception here
}
my javascript code (jQuery):
$.post('next_page.php', {
form_variant: form_variant,
person: person,
last_page: last_page,
direction: "forward"
},
function(data) {
var response = JSON.parse(data);
window.location = response.new_page;
});
Initialing the POST request from javascript this is fine, but I am also working with some legacy code and would need to get the new page address from the form controller but I can't figure out how to call the FormController because that needs to use the $_POST variable.
One compromise is that I could have the form controller accept normal arguments and validate any post requests before I construct the FormController. This way I can contruct it from a PHP page.
Sorry for the length of this question, but can anyone tell me how I could make a POST request from within a PHP page? Or even if there is a better way I could be designing this?
Many thanks
In your formController allow $_POST vars being sent to be overwritten with a passed array:
public function __constructor($data = array())
{
if(!sizeof($data))
{
$data = $_POST;
}
}
Then send it directly when required:
$controller = new FormController($data);
You are using ajax just to get the post url and then do a redirection?
Why not just post to the nextpage, and let the nextpage decide what your want to forward to.

CodeIgniter, Accessing class property after page reloads, is it possible?

I have a CI page that will load to a div in view file, using jQuery. Using switch(page_parameter), I control what is showing from the page.
When I call the page for 3rd time, I set a value to the class array.
But when I call the 4th time, the array become empty.
I was wondering, is it actually possible to use the class property to store value that can be used after page re-access? Or something missing in my head?
I know that using session is not a good idea, since the real array is a big chunk of serialized xml.
Here's my code:
class MyClass extends MY_Controller
{
public static $pitems = array();
function Hotel(){
parent::MY_Controller();
}
function new_campaign(){
$params = $this->uri->uri_to_assoc();
switch($params['step']){
case '3' : self::$pitems = array("test","another"); //here the class array was set successfully
$this->load->view('viewer');
break;
case '4' : print_r(self::$pitems); //here the array is empty
break;
}
}
In the viewer page, there's a call to the page:
Next page
Same issue also with $this->
What am i missing here?
Thanks in advance~
edit:
I saw a script that has similar scenario. it successfully reused the variable set in the constructor, instead of treating it as a class variable. i'll look thorough to confirm this, but for now, i'll close this thread. Thanks Chris for sharing.
Im not really sure what your trying to do but I have users jQuery post()/get()/ajax() many of times in CI and have had no problems. So despite not knowing or understanding what your trying to do. I thought I'd at least say I know loading data without refresh in CI through something like jQuery isn't an issue. Example on system I built on CI had a twitter like feed of tweets where jQuery on a timer was polling for new data and coming back with it each time accordingly if something new was to be shown.

Categories