How to add a new php file to mvc concept - php

How to use the mvc concept,
I need to add a php file to mvc concept.
Please explain

Before you start adding files, you need to understand what MVC is, i assume that you understand what a controller, model and view is, ok i will try to explain step-by-step on how to add a file. Let's say you want to create a page that grabs some product info from database and shows that on a page called products.php.
Step 1: You create a controller named products.php and put all the variables that will be passed to view as well as function to grab products info from db through model.
Step 2: You create a model named products.php and write a function it it that will grab the product info from db.
Step 3: You create a view named products.php and show all variables coming from controller as well as any html for the layout.
Here is the basic skeletion:
products.php controller
class products_controller extends controller
{
// set a variable to be shown on the view
$this->view->myvariable = 'Our Products';
// call model function to get info from db that will be shown on the view.
$this->load->model('products');
$this->view->db_products = $this->products->getProducts();
// now render the view
$this->view->render();
}
products.php model
class products_model extends model
{
function getProducts()
{
$result = mysql_query("select * from products_table");
$rows = mysql_fetch_assoc($result);
return $rows;
}
}
products.php view
<html>
........
<?php echo $myvariable; // this var comes from controller?>
<?php
// now show products coming from db
foreach ($db_products as $product)
{
echo $product['name'];
echo $product['price'];
echo $product['etc'];
}
?>
........
</html>
Note: This is just an example but depending on which MVC framework you are using, file names and class names or syntax might look different, so you will have to adjust that. However, i have put in the code from my own MVC framework named EZPHP, and as the name suggests, it is very easy to use MVC framework. If you need it just reply through a comment.
Thanks and hope that helps :)

Related

How to call function from controller in different view in cakephp 3?

I have function in ProductsController productsCount(). It give me amount of records in table.
public function productsCount() {
$productsAmount = $this->Products->find('all')->count();
$this->set(compact('productsAmount'));
$this->set('_serialize', ['productsAmount']);
}
I want to call this function in view of PageController. I want to simply show number of products in ctp file.
How can i do this?
You can use a view cell. These act as mini controllers that can be called into any view, regardless of controller.
Create src/View/Cell/productsCountCell.php and a template in src/Template/Cell/ProductsCount/display.ctp
In your src/View/Cell/productsCountCell.php
namespace App\View\Cell;
use Cake\View\Cell;
class productsCountCell extends Cell
{
public function display()
{
$this->loadModel('Products');
$productsAmount = $this->Products->find('all')->count();
$this->set(compact('productsAmount'));
$this->set('_serialize', ['productsAmount']);
}
}
In src/Template/Cell/ProductsCount/display.ctp lay it out how you want:
<div class="notification-icon">
There are <?= $productsAmount ?> products.
</div>
Now you can call the cell into any view like so:
$cell = $this->cell('productsCount');
I think it would make more sense to just find the product count in the PageController. So add something like $productsAmount = $this->Page->Products->find('all')->count(); in the view action of PageController, and set $productsAmount. If Page and Products aren't related, then you can keep the find call as is as long as you include a use for Products.
Also check this out for model naming conventions: http://book.cakephp.org/3.0/en/intro/conventions.html#model-and-database-conventions
Model names should be singular, so change Products to Product.
you can not call controller method from view page. you can create helper, which you can call from view page.
here you will get a proper documentation to creating helpers-
http://book.cakephp.org/3.0/en/views/helpers.html#creating-helpers
It just depend on the kind of call you're making because there are 3 cases for your issue..
1- If you're calling by a link to click you simply do:
<?= $this->Html->link(_('Product number'),['controller' =>'ProductsController', 'action' => 'productsCount']) ?>
The 2 other cases are whether you want to render the result straight in that same view, then there are some workaround to do.
1- first you will need to check what are the associations between the Page table and the product table and use BelongTo or hasMany option to bind them togheter for proper use.
2- If no association between the tables then you will nedd TableRegistry::get('Produts'); to pass data from a model to another, just like this way in the Pages controller:
public function initialize()
{
parent::initialize();
$this->Products = TableRegistry::get('Produts');
}
But i quite believe that the first option is more likely what you described.
Also you can define static method as below
public static function productsCount() {
return = $this->Products->find('all')->count();
}
And use self::productsCount() in other action.
This is useful only if you need to get count multiple time in controller. otherwise you can use it directly in action as below:
$this->Products->find('all')->count();

Passing database results into header file in PHP-MVC

I'm starting a new project using the http://www.php-mvc.net framework but have never had to include database results in the header file before and not sure how to go about it. I need to pull a list of current categories and there ID's from the database and use them to populate a menu.
The header.php file is in /views/_templates. The normal way of passing database results to the view is to run the query in the relevant model, get the data in the controller, pass the data from the controller to the view, then loop over the data with a foreach loop in the view. The problem being the _template files don't have any kind of controller for them.
The best I can come up with is to use include and include a view file from the home controller, using that controller to get the results and pass them to a menu.php in the views/home folder.
/views/_templates/header.php
<li class="dropdown">
<?php include 'views/home/menu.php'; ?>
</li>
/views/home/menu.php
foreach ($links as $link){
<li><?php echo $link->name; ?></li>
}
the above code has been shortened its more for principle than a working example.
The method I have come up with works but I wanted to know if there's a more elegant way of doing things?
As I commented:
No need to store in session you could use a Twig global so its available in all templates and you could make sure that your base controller runs a preExceute to pull all the data together and then add that global.
That might look something like this:
abstract class MyBaseController extends Controller
{
private $view = null;
private prepareView()
{
$twig_loader = new Twig_Loader_Filesystem(PATH_VIEWS);
return new Twig_Environment($twig_loader);
}
public function getView()
{
if ($this->view === null) {
$this->view = $this->prepareView();
}
return $this->view;
}
protected function preRender()
{
// whatever logic you need to prepare the menu data as $links
$this->getView()->addGlobal('links', $links);
}
public function render($view, $data_array = array())
{
$this->preRender();
// render a view while passing the to-be-rendered data
echo $this->getView()->render($view . PATH_VIEW_FILE_TYPE, $data_array);
}
}
Now depending on what data you need to build your stuff for $links you may or may not need to get a bit more elaborate. Especially given how the URL params are handled in the Application class. I really hope you're only doing this as a learning experience because this "framework" you've found isn't really good for much other than learning how you might implement MVC.

PHP, understanding MVC and Codeigniter

I'm trying to understand MVC, and learning CI framework. I've some questions about MVC and some basic questions about CI.
1)Views are visual part of application as i read from tutorials, my question is: e.g There is a button "Login" but if user already logged in button will be "Logout". Where will that login check be? On controller or on view? i mean
//this is view//
<?php if($_SESSION('logged') == true):?>
Logout
<?php else: ?>
login
<?php endif; ?>
or
//this is controller//
if($_SESSION('logged') == true)
$buttonVal = 'logout';
else
$buttonVal = 'login';
//and we pass these value to view like
$this->view->load('header',$someData);
//this time view is like
<?=$somedata['buttonVal']?>
i just write theese codes as an example i know they wont work, they are imaginary codes, but i guess you got what i mean. Login check should be on controller or on view?
2)Should models contain only codes about data and return them to controller? For example there is a math, we get 2 value from database and multiply them and display them. Model will multiply or controller will do it?
here we load data with model and do math on controller:
//model
$db->query(....);
$vars=$db->fetchAll();
return $vars;
//controller
$multi = $vars[0] * $vars[1];
$this-load->view('bla.php',$mutli);
here we load data with model and do math on model too, controller just passes data from model to view:
//model
$db->query(....);
$vars=$db->fetchAll();
$multi = $vars[0] * $vars[1];
return $multi;
//controller
$multi = $this->model->multiply();
$this-load->view('bla.php',$mutli);
i mean with that, models should do only database works and pass data to controllers, controller do rest of work and send view to render? Or models do work, controllers get them and send them to view?
3)This is about codeigniter, i have a header which has to be in every page, but it has javascripts,css depending to page i'm using
<?php foreach ($styles as $style): ?>
<link id="stil" href="<?= base_url() ?>/css/<?= $style ?>.css" rel="stylesheet" type="text/css" />
<?php endforeach; ?>
this will be on every page, so in every controller i have
$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);
i'm thinking to make a main controller, write this in it, and all my others controllers will extend this, i see something MY_Controller on CI wiki, is this MY_Controller same with what i'm doing? Are there any other ways to do this?
Sorry for bad English and dummy questions. Thanks for answers.
This is absolutely view logic, the correct way to do it in my opinion:
<?php if($logged_in):?>
Logout
<?php else: ?>
login
<?php endif; ?>
The value of $logged_in would probably be retrieved from a call to a library method:
<?php if ($this->auth->logged_in()): ?>
Authentication is one of those things you'll want access to globally, so you may be calling $this->auth->logged_in() in controller or views for different reasons (but probably not in models).
In every controller i have
$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);
Yes you could extend the controller class with MY_Controller, but you're better off keeping this in the view/presentation layer. I usually create a master template:
<html>
<head><!-- load assets --></head>
<body id="my_page">
<header />
<?php $this->load->view($view); ?>
<footer />
</body>
</html>
And write a little wrapper class for loading templates:
class Template {
function load($view_file, $data) {
$CI = &get_instance();
$view = $CI->load->view($view_file, $data, TRUE);
$CI->load->view('master', array('view' => $view));
}
}
Usage in a controller:
$this->template->load('my_view', $some_data);
This saves you from loading header/footer repeatedly. In my opinion, presentation logic like which CSS file to load or what the page title should be belongs in the view whenever possible.
As far as models go, you want them to be reusable - so make them do what you need and keep it strictly related to data manipulation (usually just your database). Let your controller decide what to do with the data.
Not related to MVC, but in general you want to write as little code as possible. Redundancy is a sign that you could probably find a better solution. These are broad tips (as is your question) but hopefully it helps.
1) View logic should be simple and mostly if-then statements, if needed. In your example, either case would work but use the logic in the view. However, if you were checking for login and redirecting if not logged in, then that would occur in a controller (or a library).
2) Think of Codeigniter models as ways to access database functions - Create, Retrieve, Update, Delete. My (loose) rule of thumb is for Codeigniter models is to return results from update, delete or insert queries or a result set from a fetch query. Any applicable math can then occur in the controller. If this is a math operation that occurs EVERY time, consider adding it to a library function. See below...
3) Extending the controller is the proper and best way to accomplish this.
*) Not to add more to your plate, but also be sure to learn about Codeigniter Libraries. For example, in your controller you could load your library. You then call your library function from your controller. The library function calls a model which retrieves your database result. The library function then performs math on that function and returns the result to the controller. The controller is left with little code but a lot is accomplished due to the library and model.
The user lo-gin check should be in the controller.
This should be the first function that need to be invoked in the constructor.
Below i have given the sample code which redirects the user to the login page if he is not logged in, hope this would give you some idea,
<?php
class Summary extends Controller {
function Summary() {
parent::Controller();
$this->is_logged_in();
}
function is_logged_in() {
$logged_in = $this->session->userdata('logged_in');
if (!isset($logged_in) || $logged_in != true) {
$url = base_url() . 'index.php';
redirect($url);
exit();
}
}
?>
The button change can be implemented in the view by checking the session variable in view and making decisions accordingly.
Please take look at this link

How can I use MVC ideas without using classes?

As of right now, I am still shaky on classes, so I don't want to use any classes for my site. I'm still practicing with classes.
But how can I implement the MVC idea without classes?
Would this work for a MVC?
index.php (the view)
index_controller.php
index_model.php
Is this right for what a MVC should be?
View: show html, css, forms
Controller: get $_POST from forms and any data from the user, get info from db
Model: do all the functions, insert/delete in db, etc
Basically separate the HTML/css for the view, all the data collecting for the controller, and the logic for the model. And just connect them all using require_once.
Controller: Your index.php, accepting and directing requests. This can certainly be a 'classless' script. It would act as both controller and 'front controller'.
View(s): A collection of presentation scripts, specific script included by your controller. Essentially 'getting' data from the variable scope of the controller.
Model(s): A collection of functions that provide access to your data. The controller determines what to include for a request.
Sure, it can be done, but you loose a lot not using classes (OOP). Here's a quick example of what the controller might look like. Nothing amazing, just an idea. Showing the controller should shed some light on the model/view as well.
<?php
$action = getAction(); //parse the request to find the action
switch($action){
case 'list':
include('models/todolist.php'); //include the model
$items = todolistGetItems(); //get the items using included function
include('views/todolist/list.php'); //include the view
break;
case 'add':
if(!empty($_POST['new'])){
include('models/todolist.php'); //include the model
todolistAddItem($_POST); //add the item
$items = todolistGetItems(); //get the items using included function
include('views/todolist/list.php'); //include the view
} else {
include('views/todolist/add.php'); //include the view
}
}

What is an example of MVC in PHP?

I'm trying to understand the MVC pattern. Here's what I think MV is:
Model:
<?php
if($a == 2){
$variable = 'two';
}
else{
$variable = 'not two';
}
$this->output->addContent($variable);
$this->output->displayContent();
?>
View:
<?php
class output{
private $content;
public function addContent($var){
$this->content = 'The variable is '.$var;
}
public function displayContent(){
include 'header.php';
echo $content;
include 'footer.php';
}
}
?>
Is this right? If so, what is the controller?
The controller is your logic, the model is your data, and the view is your output.
So, this is the controller:
$model = new UserDB();
$user = $model->getUser("Chacha102");
$view = new UserPage($user->getName(), $user->getEmail());
echo $view->getHTML();
The model is the UserDB class which will give me my data. The view is the UserPage that I give the data from the model to, and it will then output that page.
As you can see, the controller doesn't do much in this example, because you are simply getting user data and displaying it. That is the beauty of MVC. The controller doesn't have to deal with the User SQL or HTML stuff, it just grabs the data and passes it to the view.
Also, the view doesn't know anything about the model, and the model doesn't know anything about the view. Therefore, you can chance the implementation of either, and it won't affect the other.
Relating more to your example, you have the view correct, but you have mixed your controller and model.
You could relieve this by:
Controller:
$model = new NumberToWord();
$word = $model->getWord($a);
$this->output->addContent($word);
$this->output->displayContent();
Model:
class NumberToWord{
public function getWord($number)
{
if($number == 2){
return 'two';
}
else{
return 'not two';
}
}
}
And keep your same output
Controllers receive user requests - usually there is some kind of router that takes a URL and routes the request to the appropriate controller method.
Models are used by a controller to query data to/from a database (or other data source).
Views are called from a controller to render the actual HTML output.
If all you want to do is create a simple template system, you might aswell go with:
$content = 'blaba';
$tpl = file_get_contents('tpl.html');
echo str_replace('{content}',$content,$tpl);
With a template file like:
<html>
<head><title>Whatever</title></head>
<body>{content}</body>
</html>
In your example, it's more like you've split a Controller into a Model and a View.
Model: Business logic / rules and typically some sort of database to object relational mapping
Controller: Responds to url requests by pulling together the appropriate Model(s) and View(s) to build an output.
View: The visual structure the output will take. Typically a "dumb" component.
It can be confusing when you first encounter MVC architecture for a web app, mainly because most web frameworks are not MVC at all, but bear a much closer resemblance to PAC. In other words, the Model and View don't talk, but are two elements pulled together by the context the Controller understands from the given request. Check out Larry Garfield's excellent commentary on the subject for more information:
http://www.garfieldtech.com/blog/mvc-vs-pac
Also, if you are interested in the MVC pattern of development, I suggest you download one of the many frameworks and run through a tutorial or two. Kohana, CodeIgnitor, CakePHP, and Zend should be enough to kick-start a Google-a-thon!
Zend Framework: Surviving The Deep End has some good sections explaining MVC. Check out the MCV Intro and especially this seciton on the model.
There are numerous interpretations of the Model but for many programmers the Model is equated with data access, a misconception most frameworks inadvertently promote by not obviously acknowledging that they do not provide full Models. In our buzzword inundated community, many frameworks leave the definition of the Model unclear and obscured in their documentation.
To answer "where's the controller":
Controllers must define application behaviour only in the sense that they map input from the UI onto calls in Models and handle client interaction, but beyond that role it should be clear all other application logic is contained within the Model. Controllers are lowly creatures with minimal code who just set the stage and let things work in an organised fashion for the environment the application operates in.
I think you'll fine it (and his references of other articles and books) a good read.
Here is a very simple example of MVC using PHP. One thing missing is THE router. It selects one of the controller to do the job. We have only one controller, the customer.
If we compare it with 3 tiers
Model: The database
View: Client
Server:Controller
Router:It selects a controller
When you select something from an application on web browser, the request goes to router, from router it goes to controller. Controller asks from model and make a view. View is rendered to you.
Only model can talk to controller back and forth.
1- Model.php
<?php
class Model
{
private $con=null;
private $r=null;
function connect()
{
$host="localhost";
$db="mis";
$user="root";
$pass="";
$this->con=mysqli_connect($host,$user,$pass) or die(mysqli_error());
if(!$this->con){
echo die(mysqli_error());
}
else mysqli_select_db($this->con,$db);
}
function select_all()
{
$this->connect();
$sql="select * from customers";
$this->r=mysqli_query($this->con,$sql) or die(mysqli_error());
return $this->r;
}
function display_all()
{
$i=0;
echo "aaaaaaaaaa";
$this->r=$this->select_all();
while($q=mysqli_fetch_array($this->r))
{
$i++;
echo $i."-Id:".$q['id']."</br>";
echo $i."-Name:".$q['name']."</br>";
echo $i."-Phone:".$q['phone']."</br></br>";
}
}
}
?>
2. Controller: There may may be many controllers.
<?php
class Customers extends Model
{
function select_all1()
{
//echo "aaaaaaa";
$this->display_all();
}
}
?>
3. View: There may be many views
<?php
include("model.php");
include("customers.php");
?>
<html>
<head><title>Customers</title></head>
<body>
<?php
$c=new Customers();
echo $c->select_all1();
?>
</body>
</html>

Categories