PHP website developed using MVC pattern. i want access an object created using constructor in all functions of class. when i check is_object its not there so i create object one more time.
When try to simulate the MVC pattern its working fine(below code) getting Object Accessible: $this->ldap Logged In!. But in my actual website getting as Non-Object: $this->ldap Logged In!
What could be possible mistakes i done? is there anyway to find what
is the issue?
class ldap{
function ldap_userAuth(){
return TRUE;
}
}
class commonfunctions {
private $ldap;
public function __construct(){
$this->ldap=new ldap();
}
function userLogin(){
if(!is_object($this->ldap)){
$this->ldap=new ldap();
echo 'Non-Object: $this->ldap'.PHP_EOL;
}
else{
echo 'Object Accessible: $this->ldap'.PHP_EOL;
}
if($this->ldap->ldap_userAuth()){
return TRUE;
}
else{
return FALSE;
}
}
}
class Model extends commonfunctions {
}
class Controller {
public $model;
public function __construct(){
$this->model = new Model();
}
public function invoke(){
if($this->model->userLogin()){
echo 'Logged In!'.PHP_EOL;
}
else{
echo 'Logged Out!'.PHP_EOL;
}
}
}
$controller = new Controller();
$controller->invoke();
Note:- classes are included in the above order for my actual website.
Above Code snippet is working as expected i have issue only in live website.
Try calling the __construct method of the parent in the Model class like this:
class Model extends commonfunctions {
public function __construct(){
parent::__construct();
}
}
to make sure that the constructor is being called.
Related
I am new to PHP OOPs and I have a problem where I want to access the member data and functions of one class in another class. I google it but not getting any perfect solution.
Here is my example code:
class school{
public function teacher()
{
$teacher_name='Ali Raza';
}
public static function students()
{
echo"STUDENT DATA: Jhon Deo";
}
}
class library{
public function teacher_name()
{
// Now here i want to acces the name of teacher form above class function teacher.
}
public function student_name()
{
// Now here i want to access the member function(students) from school class.
}
}
I am new here. Thanks in advance.
Try this for accessing function of class school into class library function:
class school {
public function teacher()
{
$teacher_name='Ali Raza';
}
public function students()
{
echo"STUDENT DATA: Jhon Deo";
}
}
class library {
public function teacher_name()
{
// Now here i want to acces the name of teacher form above class function teacher.
}
public static function student_name()
{
echo School::students();
}
}
You need to instantiate the class that has the data you want to access. Or, you can define the data static and access it without instantiating.
Take a look at this:
class library{
private $getTeacherInstance;
public function teacher_name()
{
if(!$getTeacherInstance) // if instance is not created
$this->getTeacherInstance = new school(); // then get a new instance
return $this->getTeacherInstance->teacher(); // call the method exists inside `school class`
}
}
Make your teacher() function to return some data like "Teacher's name"
Try this one. This is a php class that inherits the from school class to library class.
The main function will access the data needed through the library class that takes the data from school class.
Hope this helps
<?php
class school{
public $teacher_name;
public $students_name;
public function getTeacherName(){
return $this->teacher_name;
}
public function setTeacherName(){
$this->teacher_name = "Ali Raza";
}
public function getStudentName(){
return $this->students_name;
}
public function setStudentName(){
$this->students_name = "Ali Raza";
}
}
/**
*
*/
class library extends school
{
//this will get the value from class school
}
function showAll(){
$showAll = new library();
$showAll->setTeacherName();
echo "Teacher Name: " . $showAll->getTeacherName() . '<br>';
echo "Studnet Name: ". $showAll->getStudentName();
}
showAll();
In my class, we made a simple application using MVC with the observer pattern in Java and it works. The view cannot call any methods from the model that are not included in the (Observable) interface and vice versa.
I am quite a fan of PHP and decided to make the same (simplified) example in PHP. I noticed that even though I am using an interface and passing the reference of the model as an interface, the view can still call every method inside the model, rendering the entire pattern useless.
Is there something I overlooked or is this not possible in PHP?
The PHP code (every reference, method, etc is the exact same as in the Java application) :
class App
{
public function __construct()
{
$model = new Model();
$controller = new Controller($model);
}
}
class Model implements Observable
{
private $view;
private $count = 1;
public function __construct()
{
echo 'Model created. <br>';
}
public function registrate(Observer $view)
{
$this->view = $view;
echo 'Model: view is registered. <br>';
}
public function addOne()
{
$this->count += 1;
$this->view->modelChanged($this);
}
public function getCounter()
{
return $this->count;
}
public function getMessage()
{
return 'The view should not be able to call this method.';
}
}
class Controller
{
private $view;
private $model;
public function __construct(Model $model)
{
echo 'Controller created. <br>';
$this->model = $model;
$this->view = new View($this->model);
$this->model->addOne();
}
}
class View implements Observer
{
public function __construct(Observable $model)
{
echo 'View created. <br>';
$model->registrate($this);
}
public function modelChanged(Observable $model)
{
// Should only be able to call method "getCounter()"
echo $model->getMessage();
}
}
interface Observable
{
public function registrate(Observer $view);
public function getCounter();
}
interface Observer
{
public function modelChanged(Observable $model);
}
The output, if you run this is:
Model created.
Controller created.
View created.
Model: view is registered.
The view should not be able to call this method. As you can see, the view can call a method of the model that is not declared inside the Observable interface.
How is this possible and why does this not work in PHP like it does in Java?
Well of course the view can call every method you've defined on the model: All the methods are public, which means they're callable from anywhere. Just define them as protected or private instead...
Of course, that'd limit the ways in which you can use the model in other components (such as the controller). To get around that problem, a simple fix would be to create a wrapper, which you can wrap around the model when you pass it to the view:
class View implements Observable
{
public function __construct(ViewObservable $model)
{
//do stuff here
}
}
//Wrapper:
class ViewObservable
{
/**
* #var Model
*/
protected $payload = null;
public class __construct(Observable $model)
{
$this->payload = $model;
}
public function getCounter()
{
return $this->payload->getCounter();
}
}
But really, you might want to rethink a thing or 2. It's good to use interfaces, but it doesn't make a lot of sense (to me at least) to have all components in an MVC architecture implement the same interface. All components have different jobs to perform, and therefore should have different interface requirements.
<?php
abstract class file
{
private $pid;
private $uid;
public function __construct($pid,$uid)
{
$this->pid = $pid;
$this->uid = $uid;
}
public function valid()
{
if($_SESSION['level']<$this->pid)
{
return true;
}
else
return false;
}
public function allow()
{
return "This is all right!";
}
}
?>
<?php
// put your code here
include("../file.php");
session_start();
class android extends file
{
public function __construct($pid,$uid)
{
parent::__construct($pid, $uid);
}
}
$uid = $_SESSION['id'];
$pa = new android(1,$uid);
if($pa->valid())
echo $pa->allow();
else
echo "<h1>No permission<h1>"
?>
The above class is android class and the one above that is file.. Now when the android extends(inherits) the file class, it means it has all the methods. But when I try to run the program, it says undefined variable android::allow()
I dont understand because I have defined the allow() function in the file class and so the android class should inherit the method as well.
please help.. Thanks in advance.
According to http://www.php.net/manual/en/language.oop5.abstract.php ,
Classes defined as abstract may not be instantiated
If your file class doesn't have any abstract method, don't bother declaring it as abstract, otherwise avoid calling the constructor ;)
The task is to protect calling public controller's methods; we need to check if user is administrator or not before calling.
class AdminController {
final public function __call($name, $arguments) {
if (!Auth::isAuth()) {
$User = UserFactory::loadById(Auth::getUserId());
if (!$User->isAdmin()) {
throw new ForbiddenException();
}
}
return call_user_func_array(array($this, $name), $arguments);
}
}
class AdminCategoryController extends AdminController {
public function view() { //__call() won't be called bacause it is public method
}
}
We can use magic __call() method, but we need all methods to be private.
Another way I see is to define final public __construct() at AdminController and put checking $User->isAdmin() there...
Any other ideas?
Thank you.
Create a new method in your base controller (BaseController) called isSecure():
public function isSecure() {
return false;
}
Then in your controller that must be secure (AdminBaseController) override the method with:
public function isSecure() {
return true;
}
AdminBaseController extends BaseController and AdminCategoryController should extend AdminBaseController.
Then at any point you can call $Controller->isSecure() on any controller to find out if it must be secure or not.
So in your dispatch code you could use something like this (obviously needs refactoring):
if($Controller->isSecure()) {
if (!Auth::isAuth()) {
$User = UserFactory::loadById(Auth::getUserId());
if (!$User->isAdmin()) {
throw new ForbiddenException();
}
} else {
$Controller->view();
}
}
I have a big problem. How to get called subclass method from a superclass. Please execute below code.
class Model {
public function render(){
echo '<br />class: '.get_class($this).' -- function: '.__FUNCTION__;
}
}
class Product extends Model {
public function show(){
$this->render();
}
}
class User extends Model {
public function index(){
$this->render();
}
}
$p = new Product();
$u = new User();
echo $p->show();
echo $u->index();
result :
class: Product -- function: render
class: User -- function: render
How to get subclass method name instead of render?
Thanks.
You can get that information using debug_backtrace().
I am curious as to why you want this - it could indicate a flaw with your design if you need this for anything other than debugging.
The __FUNCTION__ thingie is replaced at compile-time by the name of the function it is in. So no matter how your object model is structured, you'll get the function where __FUNCTION__ is met by PHP's preprocessor.
The best you can do here, if you want to know the name of the method being called, is to add it as a parameter to the method render() :
class Model {
public function render($methodName){
echo '<br />class: '.get_class($this).' -- function: '. $methodName;
}
}
And add the name in the method calls :
class Product extends Model {
public function show(){
$this->render(__FUNCTION__);
}
}
class User extends Model {
public function index(){
$this->render(__FUNCTION__);
}
}
Could you go into detail as to why you need this?
I'm not sure what you are trying to do, but especially when you are developing a PHP framework you should restrict yourself to the basic rules of inheritance.
Maybe you could illustrate a little better what you're trying to achieve with this.
Couldn't you simply change it to the following?
class Model {
protected $_type='unspecified';
public function render(){
echo '<br />class: '.$this->_type.' -- function: '.__FUNCTION__;
}
}
class Product extends Model {
public function __construct(){
$this->_type = 'product';
}
public function show(){
$this->render();
}
}
class User extends Model {
public function __construct(){
$this->_type = 'user';
}
public function index(){
$this->render();
}
}
Or is there any reason why that doesn't work for you?
You could move the logic which works out what you are rendering into the superclass, e.g.:
class Model {
public function render($type){
echo '<br />class: '.get_class($this).' -- function: '.$type;
}
public function show() {
$this->render('show');
}
public function index() {
$this->render('index');
}
}
class Product extends Model {
public function show(){
//some stuff
parent::show();
}
}
class User extends Model {
public function index(){
parent::index();
}
}
I don't really recommend this to you, but what you could do is throw an exception and catch it right away.
Then you can use the stack trace of this exception to find out which function called your render method.
I know that it works, but both performancewise and codingwise this is not a good option.
UPDATE:
<?php
class bla {
function test1() {
$this->test2();
}
function test2() {
$method = "";
try {
throw new Exception("bla");
} catch(Exception $e) {
$trace = $e->getTrace();
$method = $trace[1]['function']);
}
echo $method; //will echo test1
}
}
$blub = new bla();
$blub->test1();
Hope you get what I'm trying to illustrate.