is possible to connect two class like this ?
we want first login with admin class then use $user without passing variables
class app {
$user;
}
class admin extends app {
function login() {
$this->user = "lamar";
}
}
class song extends app {
function add() {
// add somthing with $this->user
}
}
$admin = new admin();
$admin->login();
now how to use class song to add song with user "lamar" ?
Connecting classes and use their values without passing variables is not possible. Have a look at dependency injection to get access to a class within another.
Regarding to your example it could look like this:
class User {
private $username;
function getUsername() {
return $this->username;
}
}
class Song {
private $user;
function __construct(User $user) {
$this->user = $user;
}
function getUser() {
return $user;
}
}
It might be a good idea to optimize your approach for app, admin and song otherwise your architecture could become quite complicated.
Related
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.
Here is sample code:
namespace myApp
class app
{
private $pdo = null;
public function __construct() {
$this->user=new User();
$this->user->getPDO();
}
}
class User
{
public function getPDO() {
//get PDO from app class
}
}
How from User class get $pdo from app class??
Can't use extends because of construct in app class.
I don't want to declare independent classes (app and User) and than use global to communicate with each other.
EDIT:
is this solution ok?
namespace myApp
class app
{
public $pdo = null;
public function __construct() {
$this->user=new User($this);
$this->user->getPDO();
}
}
class User
{
private $app=null;
public function __construct($app) {
$this->app=$app;
}
public function getPDO() {
return $this->app->pdo;
}
}
This sounds like a good candidate for dependency injection.
You can declare the constructor for your Userclass for example like
__constuct($pdo) {
$this->pdo = $pdo;
}
And then create User like
$this->user = new User($this->pdo)
An added advantage of this is that when you want to test your code you can easily mock pdo and test user without doing actual database actions.
You have to declare 2 functions in your app class like this:
Then you have acces through this functions to the pdo variable
public function setPDO($pdo) {
$this->pdo = $pdo;
}
public function getPDO() {
return $this->pdo;
}
I'm playing around with OOP in PHP and I've got the following code:
index.php:
<?php
include('user.class.php');
include('page.class.php');
$user = new User;
$page = new Page;
$page->print_username();
?>
user.class.php:
<?php
class User {
public function __construct() {
$this->username = "Anna";
}
}
?>
page.class.php:
<?php
class Page extends User {
public function __construct() {
}
public function print_username() {
echo $user->username;
}
}
?>
My problem occurs in the class "Page", in the print_username() function.
How do I access the $user object's properties within this class? I am, as you can see, defining the two objects in index.php.
Thanks in advance
/C
class User {
public $username = null;
public function __construct() {
$this->username = "Anna";
}
}
class Page extends User {
public function __construct() {
// if you define a function present in the parent also (even __construct())
// forward call to the parent (unless you have a VALID reason not to)
parent::__construct();
}
public function print_username() {
// use $this to access self and parent properties
// only parent's public and protected ones are accessible
echo $this->username;
}
}
$page = new Page;
$page->print_username();
$user should be $this.
class User {
public $username = null;
public function __construct() {
$this->username = "Anna";
}
}
class Page extends User {
public function print_username() {
echo $this->username; //get my name! ($this === me)
}
}
I see some confusion here:
You've caused your Page class to inherit from User. This means that the page itself has all the properties of the User class, and in fact, could be used in place of a User class. As the print_username() method is written in your code, it won't work - because it doesn't have a reference to a $user variable. You could change $user to $this to get a username in the print_username() method, and borrow from the parent class (User) to get the username property.
My thinking is though, that you didn't intend to do that. A Page is not a User, after all - they aren't related to each other. So what I'd do instead is remove extends User from the Page class. This will make a Page a Page, and a User a User.
But how is the Page going to print a username? Pages need to do that of course. What you could do instead is pass the $user object as a parameter to the Page's __construct() method, and then you can reference that value in your Page.
The first way of writing the code, using extends, involves inheritance. The second way of writing the code when passing in the user as a parameter involves composition. In a situation like this, with two separate ideas (Pages and Users), I would use composition to share and access object properties instead of inheritance.
I would do this instead:
<?php
class User {
public function __construct() {
$this->username = "Anna";
}
}
class Page {
private $user;
public function __construct($user) {
$this->user = $user;
}
public function print_username() {
echo $user->username;
}
}
$user = new User;
$page = new Page($user);
$page->print_username();
?>
After restructuring my entire class layout, I'm still having trouble using multiple class instances.
class User {
public $variable;
public function getUser() {
$this->variable = 'It works!';
return 'bob';
}
}
class Base {}
class One extends Base {
public function test() {
print_r($User->variable); // Want it to print 'It works!'
}
}
$User = new User();
$username = $User->getUser();
if($username === 'bob') {
$One = new One();
$One->test(); // prints "Notice: Undefined property: One::$variable
}
What the above code does: The class User gets the username. If the username is bob, it will create an object one and try to print the variable from class User. In my real code, User is extremely intricate and passing a bunch of things with __construct just isn't what I'm looking for.
I think the solution (which is why I titled this question as so) would be to create a new class User within class Base but I just can't wrap my head around having to create a whole new object and re-initiate everything just to get the username.
Inject your User instance:
class One {
private $user;
public function __construct(User $user) {
$this->user = $user;
}
public function test() {
print_r($this->user->variable);
}
}
$User = new User();
$One = new One($user);
$One->test();
This doesn't have any undue effects with regards to efficiency, as the instance is passed by reference as opposed to copied.
The class One does not know about the $User variable and therefore can not access it.
You could either pass the variable to the class in the constructor or set it after creation of an object of the class.
class One extends Base {
protected $user;
public function setUser(User $user) {
$this->user = $user;
}
public function One(User $user) {
$this->setUser($user);
}
public function test() {
print_r($this->user->variable);
}
}
Or (but please don't, it is bad practice) set the $User variable to global.
global $User
Not trying to spam or advertise here, I value this community and the people that gladly give up their time to answer questions (like myself). I have built an authentication library for Codeigniter called WolfAuth. It currently relies on DataMapper for all database interaction, until further notice.
Each function currently uses code along the lines of the following.
$u = new User;
$u->get_by_id($user_id);
if ( $u->exists() )
{
// Do user stuff here
}
I'm not entirely sure how PHP handles object instantiation, but surely doing this in 50 functions plus can't be good for performance, and if not, adds unnecessary object instantiation. Is it possible to have a global instantiation of each DataMapper model object I am using and re-use in each function?
So something like the following.
class Someclass {
protected $user;
protected $group;
protected $roles;
public function __construct()
{
$this->user = new User;
$this->group = new Group;
}
public function the_user($user_id)
{
$user = $this->user->get_by_id($user_id);
if ( $user->exists() )
{
echo "The user exists!";
}
}
}
Am I just being extremely picky here, or is what I am asking possible and probably the better way to do things for such a large library like I've built?
Yes, you can pass objects as arguments in php.
class Someclass {
protected $user;
protected $group;
protected $roles;
public function __construct()
{
$this->user = new User();
$this->group = new Group();
}
public function get_user($user_id)
{
if (empty($this->user->id))
{
$user = $this->user->get_by_id($user_id);
}
else
{
$user = $this->user;
}
if ( $user->exists() )
{
prove_user_exists($user);
return $user;
}
else
{
show_error('No User Found');
}
}
public function prove_user_exists($user)
{
log_message('info', $user->id);
}
Then, you can just call get_user($user_id) when you need the user - if the user has already been found, then you won't have to call the db again.