I've got Zend code which looks like this:
$contextSwitch->addActionContext('get', array('xml','json'))->initContext();
How can I change this so that it ONLY returns XML formatted data? SOrry, I'm new to Zend programming.!
Read the manual
public function init()
{
$this->_helper->contextSwitch()
->addActionContext('get', array('xml','json'))
->initContext();
}
public function getAction()
{
this->_helper->contextSwitch()->initContext('xml'); //will always use xml if action has xml context
//...
}
If you only ever use xml for a particular action, set the headers inside the action you want to return xml:
$this->getResponse()->setHeader('Content-type', 'text/xml');
And then process the rest of the action as you need it to. Without context switching enabled the view will be the default for the action (ie. actioname.phtml)
You will probably also want to disable your layout:
$this->_helper->layout->disableLayout();
Related
I want to capture every information passed to view using the afterFilter. So I need to know:
all variables
session flash
the action executed (last action)
the view called
This is because I need to check if the request is json or not for change the response.
Currently I use afterFilter like this:
public function __construct()
{
// Here's something that happens after the request
$this->afterFilter(function() {
});
}
What I want is: use the afterFilter method in BaseController to capture all events/actions and then decide if the request is json or not.
If you need more information, comment please.
And sorry for my english
Do you need to know if JSON or if AJAX? If AJAX then just use:
if (Request::ajax())
{
//
}
You may use Request::wantsJson() to determine if the request is asking for json in return using:
// In app/filters.php
App::after(function($request, $response)
{
if($request->wantsJson()) {
//...
}
});
In this case, Laravel (through Base/Symfony class) checks if the Accept header is set and if that is application/json.
I'm evaluating frameworks for use with an API, and I'm taking a serious look at PHP Phalcon. It's looking promising - "lean" (load what you need), but with a lot of options.
I'm wondering... is it possible to not use views (templates, rather) with it? Do I have to set up a view, or can I just output .json?
Thanks!
There is a way in Phalcon to disable view in the action and avoid unnecessary processing:
public function indexAction() {
$this->view->disable();
$this->response->setContentType('application/json');
echo json_encode($your_data);
}
Depending on what you want to do you can disable the view as others have suggested and echo json encoded data, or you could use the built in response object as below:
$this->view->setRenderLevel(View::LEVEL_NO_RENDER);
$this->response->setContentType('application/json', 'UTF-8');
$this->response->setJsonContent($data); //where data is an array containing what you want
return $this->response;
There is also a tutorial in the docs that goes over building a simple REST api
http://docs.phalconphp.com/en/latest/reference/tutorial-rest.html
If you won't be using any views at all you can disable views at the very start.
$app = new \Phalcon\Mvc\Application();
$app->useImplicitView(false);
Even if you do this, I think you still have to set the view DI for the framework to work.
Also, if you want to output json there's a method for that:
$this->response->setJsonContent($dataArray);
$this->response->send();
Yeah, you can do it, I'm using PHP Phalcon.
To ignore view, in your controller your action should be like
public function indexAction() {
$var = array or other data
die(json_encode($var));
}
die(); in controller will not render any parent layout! :)
How can I echo something at the end of the cakePHP json/xml response?
I need this in order to add JSONP support (Because i need to add the callback at the beginning and the ');' at the end
The controller uses this :
public function json() {
//...code to populate $jsonObjects
$this->set('objetos',$jsonObjects);
$this->set('_serialize', 'objetos');
}
Firstly, I'm assuming you have Routes set up to correctly handle JSON/XML responses
In your routes file:
Router::parseExtensions('json');
Secondly, you would need to make sure the call to your example uses the .json extension or the Accept header is application/json
You then check for the callback in your controller
public function json() {
//...code to populate $jsonObjects
// check for callback and set it
// note: you should do Sanitize::clean() or something like that to
// prevent code injection
if ($this->request->params['callback']) {
$this->set('callback', $this->request->params['callback']);
}
$this->set('objetos',$jsonObjects);
$this->set('_serialize', 'objetos');
}
in your view file (ex: View/Users/json/index.ctp) you should have something like this:
if (isset($callback)) {
echo $callback . '('.json_encode($objetos).')';
} else {
echo json_encode($objetos);
}
I use something similar but didn't test the exact example above so you may need to clean it up. Also make sure you clean up the callback var so you aren't leaving a security hole by outputting exactly what is in the query string parameter.
I'm writing a PHP application using codeigniter framework. I'm trying to add a tool to download the data in the page as a .csv format file. I have the code to the server side, but I'm having trouble handling the URL mapping for the "Download" Controller.
in /controllers/ I have a controller called "Download", which is has a function called 'exportCSV', which receives a json object that is decoded and used to create the file. So, I'm trying to send a JavaScript array through 'post' to that method, but I'm having trouble handling the URL mapping.
here is my javascript call ...
function download(){
$.post('index.php/download/exportCSV', {input : dataForDownload.toString()},
function(answer){
alert(answer);
}
);
}
POST to index.php/download/exportcsv. CI doesn't much like Mixed Case controllers.
If you have a download controller, it should look like this:
class Download extends CI_Controller
{
function _construct()
{
parent::_construct();
}
function exportcsv()
{
if($this->input->post())
{
// Something was POSTed, continue
// process input
} else {
// Catch error if no POST
}
}
}
If you're getting a 404, your application might not be set up correctly. Check routes.php and your base_url.
I also recommend the CodeIgniter user guide. It's full of good information:
http://codeigniter.com/user_guide/overview/appflow.html
http://codeigniter.com/user_guide/overview/mvc.html
Hi out there in Stackland! Here's my problem:
I want to use my Zend controller to load an array from a database, and then pass it to javascript. I've decided the best way to do this is to use ajax to ask the controller for it's array, encode it in json, and then pass it down. However, I don't know how to pass the variable I loaded in my first action to the action that will pass it down when it gets called via ajax.
The original action which produces the view
public function indexAction()
{
$storeid = $this->getStoreId();
if(!$storeid)
{
$this->_forward('notfound');
return;
}
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
}
The action that will be called via ajax
public function getdataAction()
{
$this->_helper->Layout->disableLayout(); // Will not load the layout
$this->_helper->viewRenderer->setNoRender(); //Will not render view
$jsonResponse = json_encode($store);
$this->getResponse()->setHeader('Content-Type', 'application/json')
->setBody($jsonResponse);
}
What I want is to pass $store in indexAction to getdataAction so it can send store as the jsonResponse. Note, these are called at two different times.
Things I have tried that haven't worked:
setting $this->getRequest()->setParam('store', $store) in indexAction, and then using $this->getRequest()->getParam('store'), in getdataAction. I presume this hasn't worked because they're different http requests, so attaching a new param is useless.
using protected $_store in the controller itself, and then saving to it with indexAction, and using it in getdataAction. I'm not really sure why this isn't working.
Is there a good way to pass a variable in this manner? Is there a way to pass a variable between different controllers?(I assume the answer to one is the answer to the other). Could I store it in a controller helper? Do I have to use a session, which I know would work but seems unnecessary? Is there a better way to pass variables to javascript? Am I asking too many questions? Any help would be outstanding. Thanks.
Maybe I'm reading the question wrong, but you should be able to just move $store into the constructor:
public function __construct() {
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
}
and have it accessible in all *Action methods. Using sessions seems out of whack for this.
(disclaimer: I'm pretty new to ZF, so I'm interested in other answers found here, and have not tested the below!)
In your view, where you put the ajax call, you will probably address it like:
(See ZF Documentation)
<?= $this->ajaxLink("Example 2",
"/YourController/getdata",
array('update' => '#content',
'class' => 'someLink'),
array('store' => $this->store)); ?>
Notice that in your indexAction, you store the store via:
$this->view->store = $storeid;
Of course, you should note that a web-user could modify the store parameter as it is passed through via an URL.
It would be better architecture to simply add a method to your IndexController, a helper, or somewhere, that returns an instance of Store. Use that method within your indexAction, and your getdataAction (would be more meaningful to call it ajaxAction). Also, you're forgetting to call sendResponse() (remember, you disabled autoRender):
private function indexAction()
{
$this->getStore();
//blah blah
}
private function getStore()
{
$storeid = $this->getStoreId();
if(!$storeid)
{
$this->_forward('notfound');
return;
}
$store = $this->_helper->loadModel('stores');
$store->getByPrimary($storeid);
return $store;
}
public function ajaxAction()
{
$this->_helper->Layout->disableLayout(); // Will not load the layout
$this->_helper->viewRenderer->setNoRender(); //Will not render view
$jsonResponse = json_encode($this->getStore());
$this->getResponse()->setHeader('Content-Type', 'application/json')
->setBody($jsonResponse)
->sendResponse();
}
The manual says:
To send the response output, including
headers, use sendResponse().
http://framework.zend.com/manual/en/zend.controller.response.html
All right, for those of you who want the answer to this too, I just sucked it up and used session. I put a Zend_Session->start() in the bootstrap. I then created a plugin to add a private variable $session to each controller. Then I set $this->session to Zend_Session_Namespace. To pass something, I pass it through session, so I use $this->session->store = $store. I can then pick it up elsewhere with $this->session->store. Thanks to those who tried to help!
Just a quick addition to the comments. To output an array as JSON from within a controller, use:
$array = array('hi' => array('Hello' => 'World');
$this->_helper->json($array);
This sends the response and sets the specific headers for a JSON response