I was hoping someone could share some advice on the file structure a mobile app with jQuery Mobile, Ajax and PHP.
I am pretty new to Ajax and I am struggling to integrate it into my MVC framework.
I have my Models, Views and Controller files and normally I would simply use my Controllers to feed my Views with the data from the Models.
However, when using Ajax, I understand that you can not POST (or GET) data to a specific function in a Controller directly. (Please correct me if I am wrong)
What is the best practice here?
Create a specific Ajax Controller with no functions?
Have a separate "connecting" php-file and post the Ajax call to that file which then calls the Controller files and retrieves the data.
Any ideas and maybe even some sample code would be greatly appreciated.
Here is an example how you do it with Yii framework.
This is your ajax class 'AjaxController.php':
class UserController extends Controller
{
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
*
* #return array access control rules
*/
public function accessRules()
{
return array(
array('allow',
'actions' => array('foo', 'bar'),
'users' => array('?'),
),
array('allow',
'actions' => array('foo', 'bar'),
'users' => array('*'),
),
array('allow',
'actions' => array('foo', 'bar','regform'),
'users' => array('#'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
// [...] all the common Yii Controller functions
public function actionRegform()
{
//get some data from database
$data = Yii::app()->db->createCommand('some sql')->queryRow();
//or render a view
$this->render('regform', array('mydata' => $dataFromDb));
//push out everything you want
echo 'my function was called!';
}
}
In your javascript you just call the url /ajax/regform and your MVC will know that ajax is the controller and actionRegform the function you are calling.
Do not forget to implement your function to the access rules of this controller.
The fact that You are using AJAX doesn't change much, the simplest way to use AJAX on your site is to put an extra POST (try not to use GET) parameter with will help You to determine if this is AJAX request. It can be just ajax=1. Then You can make a seperate view to show only those things that should be shown by ajax. this can be done on every components separately, or just in Your main index.php (or whatever your mine view file is called). In this file give some code like this:
if( ( isset($_POST['ajax']) ) and ( $_POST['ajax'] == 1 ) ){
echo just_main_content();// or $component->content - whatever You use
}else{
//normal page code
}
I believe that this is the easiest way
Related
We have web pages, where user will be redirected to $this->goHome(), if the session timeouts or user logouts. We have to destroy the all the session so, we have to add a function with destroying session. This function should be executed before running any action/controller in Yii2 i.e. similar to hooks in codeigniter. We have tried a helper function with destroying session and we have called the function as HomeHelper::getHelpDocUrlForCurrentPage(); in main.php layout, but the layout will be executed after running action in controller, it should work on running any controller as we have 100+ controllers. How this can be achieved, please suggest us in right way. Thanks in advance.
in
config/main.php
you could try using 'on beforeAction'
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'bootstrap' => [
'log',
....
],
'on beforeAction' => function($event){
// your code ..
} ,
'modules' => [
....
],
...
];
While #ScaisEdge solution would work I believe application config is not proper place to hold application logic.
You should use filters to achieve result you want.
First you need to implement filter with your logic. For example like this:
namespace app\components\filters;
class MyFilter extends yii\base\ActionFilter
{
public function beforeAction() {
// ... your logic ...
// beforeAction method should return bool value.
// If returned value is false the action is not run
return true;
}
}
Then you want to attach this filter as any other behavior to any controller you want to apply this filter on. Or you can attach the filter to application if you want to apply it for each action/controller. You can do that in application config:
return [
'as myFilter1' => \app\components\filters\MyFilter::class,
// ... other configurations ...
];
You might also take a look at existing core filters if some of them can help you.
I'm working on a PHP project which has many pages calling a POST request, such as login, register, commenting and etc.
I've tried processing all POST requests in a single file named post.php, with each request containing 'formtype' parameter, like so,
$formtype = $_POST['formtype'];
if ($formtype == "register") {
register_function_here();
} else if ($formtype == 'login') {
login_function_here();
} else {
die("Error: No FORMTYPE");
}
and I've also tried having separate files for separate functions, such as login.php, register.php, comment.php and etc.
Which method is better for processing POST requests?
Are there any disadvantages for processing all POST requests in a single file, as I've done?
Thanks in advance!
I guess you mean you do not want to:
GET index.php
POST user/register.php
POST user/login.php
index.php
user/
register.php
login.php
404.php
What #ArtisticPhoenix about the MVC (model, view, controller) is actually what you tried. Well, for the Controller part i mean.
You try to create router.
You could do that. If you are new to coding and you got time i even would say: do it.
If you dont have time and need a solution then i suggest searching a framework - at least for routing.
To get started:
First i found was this: https://www.taniarascia.com/the-simplest-php-router/
If you want to go further then you SHOULD start using OOP.
A class is then a controller, a method an action.
(some got like every action is a class like zend expressive framework).
Example:
Create a routing config
// file: config/routes.php
return [
'routes' => [
[
'path' => "/login",
'class' => LoginController::class,
'method' => 'loginAction',
'allowed_methods' => ['POST'],
],
[
'path' => "/logout",
'class' => LoginController::class,
'method' => 'logoutAction',
'allowed_methods' => ['GET', 'POST'],
],
// ...
],
];
Create Controllers
// file: Controller/LoginController.php
namespace Controller;
class LoginController
{
public function loginAction()
{
// ...
}
public function logoutAction()
{
// ...
}
}
Now use the requested path and route it to the controller.
If no route found then return a HTTP 404 "Not Found" response .
// file: index.php
// load routing config
$routes = require 'config/routes.php';
// ...
// ... this now is up to you.
// you should search in the config if the requested path exists
// and if the request is in the allowed_methods
// and then create a new controller and call the method.
I strongly recommend Object Oriented Programming, using classes, one source file per class.
I am using zend framework 2.1. I am trying to load the output of my indexAction from my login controller inside of my index controller. The end result I am trying accomplish is to just have my login form loaded on the index page as if it is part of that view.
I have searched for a few hours with no avail. I have attempted to use $this->view->action, which i've seen in earlier versions of zf2 but that has not worked either.
Any information would be helpful.
Taken from this blog, which explains in depth why $this->view->action() has been removed from ZF2, an example how to use the forward() (ZF2 documentation) controller plugin:
You can forward all necessary data to another controller inside your index controller action using the forward() controller plugin like this:
public function indexAction() {
$view = new ViewModel();
$login_param = $this->params('login_param');
$login = $this->forward()->dispatch('App\Controller\LoginController', array(
'action' => 'display',
'login_param' => $login_param
));
$view->addChild($login, 'login');
return $view;
}
In your view, all you need to do is:
<?php echo $this->login; ?>
Please note that the forward() plugin might return a Zend\Http\PhpEnvironment\Response instead. This happens if you use a redirect() in your login controller / action.
Also, if the Servicemanager claims to not find App\Controller\LoginController, have a look in your module.config.php. Look for a section called controllers.
Example:
[...]
'controllers' => array(
'invokables' => array(
'LoginCon' => 'App\Controller\LoginController',
'IndexCon' => 'App\Controller\IndexController',
'DataCon' => 'App\Controller\DataController',
)
),
[...]
Here, there is an alias for your login controller called LoginCon, you should use this name as controller name in the dispatch() method instead.
how can i get an url params along with redirect url for zend php framework?
lets say i have the following URL on current page
localhost/business/microsoft
when a user click a button on that page it will redirect them to another page with the following url
localhost/comment/WavvLdfdP6g8aZTtbBQHTw?return_url=%2Fbusiness%2FWavvLdfdP6g8aZTtbBQHTw
how i can write bootstrap getRouter so it can catch the above url params? the current one seems not doing well
$router->addRoute('comment', new Zend_Controller_Router_Route_Regex(
'business/comment/id=',
array(
'controller' => 'business',
'action' => 'comment'
)
, array(
'id' => '\d+'
)
));
Thanks!!!
You'll want to write a plugin that captures the request parameters either before (preDispatch()) or after dispatch (postDispatch()) depending on whether or not you might want to intercept and redirect the request.
//basic example of controller plugin
class MyPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
return $this->getRequest->getParams();
}
}
Then register your plugin.
Below i have an ajax tab example:
$this->widget('zii.widgets.jui.CJuiTabs', array(
'tabs' => array(
'StaticTab 1' => 'Content for tab 1',
'StaticTab 2' => array('content' => 'Content for tab 2', 'id' => 'tab2'),
// panel 3 contains the content rendered by a partial view
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
),
// additional javascript options for the tabs plugin
'options' => array(
'collapsible' => true,
),
));
but i don't know what happens in /AjaxModule/ajax/reqTest01.
There is a missing part in this example, the rendering view, and i don't know how to design it so that the ajax call to work. Thanks.
According to the code you have put up, specifically this line:
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
We know that we need ajaxmodule, ajax controller, reqtest01 action, so do the following steps:
First
Create a module, it'll have to be named AjaxModule.
Second
Create a controller in this AjaxModule named Ajax.
Third
Create an action within this Ajax controller, named ReqTest01.
Within this action you can either directly echo html, or use renderPartial(), to render a view file partially for ajax.
So your controller Ajax and the action within looks somewhat like this
<?php
class AjaxController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
public function actionReqTest01(){
// directly echoing output is hardly of any use, like echo "Directly echoing this";
$this->renderPartial('rendpar_ajax'); // renderPartial is way better as we have a view file rendpar_ajax.php that we can manipulate easily
}
}
Fourth
Now we can code the rendpar_ajax.php view file, create this file in the views folder of the ajaxController controller in the AjaxModule module.
<?php
// rendpar_ajax.php file for ajax tab
// have any code here, use widgets, form, html helper etc
echo "<h1>AjaxModule--AjaxController--actionReqTest01</h1>";
echo "<p>This view is partially rendered</p>";
Read more about creating modules, controllers, actions, and how they are used, and how the yii directory hierarchy works.
Good luck!
Edit: Note that to a view we can also pass dataproviders for getting complex dynamic views.