I'm creating model structure with f3 but towards to end I stuck.
I cant access to my functions another page.
Here is error:
Fatal error: Call to a member function load() on null
[C:/UwAmp/www/test/app/models/User.php:12]
Where is wrong? Is this way good or not?
-models
----Model.php
----User.php
-controllers
----Controller.php
----UserController.php
UserController.php
class UserController extends Controller {
private $_usermodal;
public function __construct(){
parent::__construct();
}
function Register(){
$this->_usermodal = new User();
$this->_usermodal->getAll();
}
}
Model.php
class Model {
private $db;
public function __construct($table){
$this->db=new DB\SQL(
'mysql:host=localhost;port=3306;dbname=database',
'root',
'root'
);
return new DB\SQL\Mapper($this->db,$table);
}
}
User.php (model)
class User extends Model {
public function __construct(){
parent::__construct('users');
}
public function getAll(){
$x = $this->db->load('id = 1');
print_r($x);
}
}
Instead of returning a mapper instance from the __constructor (which is not possible in PHP), you could extend the framework mapper:
Model.php:
class Model extends DB\SQL\Mapper {
protected $db;
public function __construct($table) {
$this->db=new DB\SQL(
'mysql:host=localhost;port=3306;dbname=database',
'root',
'root'
);
parent::__construct($this->db,$table);
}
}
User.php:
class User extends Model {
public function __construct() {
parent::__construct('users');
}
public function getAll() {
return $this->find('',['order'=>'id']);
}
}
Now you can access your db records using the usual mapper methods:
$user = new User;
$user->load(['id=?',1]);
// or
foreach ($user->find(['name LIKE ?','%John%']) as $u)
echo $u->name;
or using your custom methods:
foreach ($user->getAll() as $u)
echo $u->name;
This structure can still be improved though as it creates a new DB\SQL instance for every fetched record. You could create a central DB service and use it by default in Model:
Index.php:
$f3->DB = function() {
if (!Registry::exists('DB')) {
$db=new DB\SQL(
'mysql:host=localhost;port=3306;dbname=database',
'root','root');
Registry::set('DB',$db);
}
return Registry::get('DB');
};
Model.php:
class Model extends DB\SQL\Mapper {
public function __construct($table,$db=NULL) {
if (!isset($db)) {
$f3=\Base::instance();
$db=$f3->DB();
}
parent::__construct($db,$table);
}
}
Related
contrller:News.php
This is my controller News
<?php class News extends CI_Controller {
public function __construct()
{
}
public function getShowIN_News()
{
return $result;
} } ?>
contrller:Category.php
This is my controller Category
<?php class Category extends CI_Controller {
public function __construct()
{
}
public function category()
{
require('news.php');
$test = new News();
$data["headlines"] = $test->getShowIN_News();
} }?>
By using an empty constructor, you're making it so that CI_Controller::__construct() isn't called, and that's where everything in the framework is initialized.
I know you've put it there to hack it so you can call one controller from another, but it is very intentionally made that way, exactly so you don't do this.
What I'm trying to do on the surface seems simple, basic OOP PHP but I just can't get it working. I have a controller class which is calling a model, that model extends another model of mine but it throws an error saying it can't find it:
Controller (Welcome.php):
public function __construct()
{
parent::__construct();
$this->load->model('users_model');
}
public function index()
{
$this->users_model->getAll();
}
Users Model (User_model.php):
class Users_model extends Base_model
{
public function __construct()
{
parent::__construct();
}
}
Base Model (Base_model.php):
class Base_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function getAll($table)
{
$query = $this->db->query('Query here');
return $query;
}
}
This gives me the error Fatal error: Class 'base_model' not found in /ci/application/models/Users_model.php on line 3
Save your Base_model in application/core named as Base_model.php with following code.
class Base_model extends CI_Model
{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function getAll($table=FALSE)
{
$query = $this->db->query('Query here');
return $query;
}
}
Save User_model in application/models named as User_model.php having following code
class User_model extends Base_model
{
public function __construct()
{
parent::__construct();
}
}
Then make a controller Welcome.php in appliation/controllers having following code with extending CI_Controller
public function __construct()
{
parent::__construct();
$this->load->model('user_model');//loads user_model
}
public function index()
{
$data = $this->user_model->getAll(); //need a variable to hold return data
}
You just have to locate the Base_model in your Users_model like below code and you can access the functions of base model easily.
require('application/models/base_model.php');
class User_model extends Base_model
{
function __construct()
{
parent::__construct();
}
}
My application have this folders stucture:
application
library
Model.php
Controller.php
View.php
models
Settings_Model.php
Home_Model.php
controllers
settings.php
home.php
views
settings
index.php
home
index.php
index.php
.htaccess
library/Model.php
class Database extends PDO{
public function __construct($DB_TYPE, $DB_HOST, $DB_NAME, $DB_USER, $DB_PASS){
parent::__construct($DB_TYPE.':host='.$DB_HOST.';dbname='.$DB_NAME, $DB_USER, $DB_PASS);
}
}
library/Controller
class Controller{
function __construct(){
$this->view = new View();
}
public function loadModel($name){
$path = 'application/models/' . $name . '_model.php';
if(file_exists($path)){
require 'application/models/' . $name . '_model.php';
$modelName = $name . '_Model';
$this->model = new $modelName();
}
}
}
library/View
class View{
function __construct(){
$this->view = new View();
}
public function render($name){
require 'application/views/' . $name . '.php';
}
}
In Models folder I created this model called Settings_Model.php : models/Settings_Model.php
class Settings_Model extends Model{
public function __construct(){parent::__construct();}
function settings(){
$stmt = $this->db->prepare("SELECT * FROM `mv_settings`");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_OBJ);
return $stmt->fetch();
}
}
In Controllers folder I have this Controller called settings.php :
controllers/settings.php
class Settings extends Controller {
function __construct(){parent::__construct();}
public function index(){
$this->view->settings = $this->model->settings();
$this->view->render('settings/index');
}
}
And In Views folder I created a folder called settings and inside this folder I created an index.php file:
settings/index
and this is how to call the settings method inside settings/index:
$this->settings->fieldName;
So now when we go to Home view, I did the same procedure:
- create a Home_Model class and inside this model I created the same settings method:
class Home_Model extends Model{
public function __construct(){parent::__construct();}
function settings(){
$stmt = $this->db->prepare("SELECT * FROM `mv_settings`");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_OBJ);
return $stmt->fetch();
}
}
and then goes to the controllers folder and create Home controller:
class Home extends Controller {
function __construct(){parent::__construct();}
public function index(){
$this->view->settings = $this->model->settings();
$this->view->render('home/index');
}
}
and then call the settings method inside home/index:
$this->settings->fieldName;
What Im asking is how to avoid not to create the same method settings again and again each time we need to call that method in another view file???
NB: Im still a newbie.
Try like this in your controller
class Settings extends Controller {
function __construct(){
parent::__construct();
$this->load->model('Settings_Model');
}
public function index(){
$this->view->settings = $this->Settings_Model->settings();
$this->view->render('settings/index');
}
}
if you want to access the same settings() function in all models then you should create it in Base model.php.
class Model{
function settings(){
$stmt = $this->db->prepare("SELECT * FROM `mv_settings`");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_OBJ);
return $stmt->fetch();
}
}
then your settings model need to be like
class Settings_Model extends Model{
public function __construct(){parent::__construct();}
}
and your Home_model
class Home_Model extends Model{
public function __construct(){parent::__construct();}
}
Now you can access settings() in all your models extending Model, no need to create it again and again.
I have a class in Laravel with a class variable that holds and object
class RegisterController extends Controller {
public $company;
When i set the variable in my index method all goes well
public function index($id = null) {
$this->company = new Teamleader\Company;
When I try to access $this->company from another method it returns
null
This is my full code
class RegisterController extends Controller {
public $company;
public function index($id = null)
{
$this->company = new Teamleader\Company;
// returns ok!
dd($this->company);
return view('register.index');
}
public function register()
{
// returns null
dd($this->company);
}
}
Am I missing something?
Thank you!
You are not __constructing() the class, you are just assigning variable inside a function inside a class, which means it is encapsulated into that function inside that class.
So if you would like to make $this->company global in class, you could use
public function __construct() {
$this->company = new Teamleader\Company;
}
In Laravel 5 you can inject a new instance of Teamleader\Company into the methods you need it available in.
use Teamleader\Company;
class RegisterController extends Controller {
public function index($id = null, Company $company)
{
dd($company);
}
public function register(Company $company)
{
dd($company);
}
}
For Laravel <5 dependency inject into the constructor.
use Teamleader\Company;
class RegisterController extends Controller {
protected $company;
public function __construct(Company $company)
{
$this->company = $company;
}
public function index($id = null)
{
dd($this->company);
}
public function register()
{
dd($this->company);
}
}
Dependency injection is better than manual invocation as you can easily pass a mock object to this controller during testing. If you're not testing, maybe someone else will be in the future, be kind. :-)
So here is my controller:
class Search extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('search_model');
$this->search_model->search_result = $_POST;
}
public function index()
{
$data['results'] = $this->search_model->get_results();
$this->load->view('search_results', $data);
}
And here is my model:
class Search_model extends CI_Model {
protected $search_query;
function __construct($search_query)
{
parent::__construct();
$this->load->database();
$this->search_query = $search_query;
}
But this doesn't seem to work. What I want to do is pass the posted form ($_POST) to my model, then do stuff with it. But it seems messy to pass $_POST to each method of my model. My plan is to extract the variables sent with $_POST and construct these as properties such as $website_url, $text_query etc..., then call these in methods with $this->website_url;
I'm relatively new to CodeIgniter so just getting to grips with the basics
for your special purpose you can try this code
Controller:
class Search extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('search_model');
$this->init();
}
private function init()
{
$this->search_model->init( $this->input->post() );
}
public function index()
{
$data['results'] = $this->search_model->get_results();
$this->load->view('search_results', $data);
}
model:
class Search_model extends CI_Model {
protected $search_query;
function __construct()
{
parent::__construct();
$this->load->database();
}
public function init( $search_query )
{
$this->search_query = $search_query;
}
you have protected $search_query; which you can't access it from your controller.
You either have to change it to public or create getter and setter for it. or just getter depending on your domain/business logic.
And it should have been obvious as you should get an error saying
Fatal error: Cannot access protected property in file some/path/to/file!
Don't put the 'search query' in your model constructor.
Controller:
class Search extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('search_model');
}
public function index()
{
if ($this->input->server('REQUEST_METHOD') == 'POST')
{
// you should probably validate/clean the post data instead
// of sending it straight to the model
$results = $this->search_model->get_where($_POST);
}
else
{
// if it's not a post, you probably need something...
// either here, or somewhere in your view to handle empty data
$results = array();
}
$data['results'] = $results
$this->load->view('search_results', $data);
}
Your Model:
class Search_model extends CI_Model {
function __construct()
{
parent::__construct();
$this->load->database(); // <--- you may want to autoload 'database' library
}
function get_where($where)
{
$this->db->where($where);
// add select, order, joins, etc here
return $this->db->get('mytable'); // whatever your table name is
}