class Model extends Database
{
function __construct()
{
if(property_exists($this, 'table'))
{
$this->table = strtolower($this::class) . "s";
}
}
whats have problem
Related
If you have an abstract class, is there a way to keep a counter inside the abstract class to count how many times it's used?
Because if I do this:
abstract class abstractClassName {
private $counter = 0;
public function __construct() {
$this->counter++;
}
public function outputCounter() {
echo $this->counter;
}
}
class someExtension extends abstractClassName {
public function __construct() {
parent::__construct();
}
}
class someExtensionTwo extends abstractClassName {
public function __construct() {
parent::__construct();
}
}
and then
$class = new someExtension;
$class->outputCounter();
$class2 = new someExtensionTwo;
$class2->outputCounter();
I get 1 twice, yet I was expecting to get 1 and then 2 on the last call, and I'm getting confused over how it's all meant to work.
Edit: changed code to reflect the real code more :)
If you are wishing to keep track of how many time the class AbstractClassName has been instantiated, you will need to make use of static variables -- so that the value of $this->counter is persistent, for example:
abstract class abstractClassName
{
private static $counter = 0;
public function __construct() {
self::$counter++;
}
public function outputCounter() {
echo self::$counter;
}
}
class someExtension extends abstractClassName
{
public function __construct() {
parent::__construct();
}
}
class someOtherExtension extends abstractClassName
{
public function __construct() {
parent::__construct();
}
}
$class = new someExtension;
$class->outputCounter();
$class2 = new someOtherExtension;
$class2->outputCounter();
Which would result in an output of: 1 & 2.
I'm trying to find a solution of my problem, but unsuccessfully. For example:
I have one main class:
class System {
public function loadClass($instance, $name)
{
$this->$instance = new $name;
}
}
And I want, that I simply can load another class into main class called System.
<?php
$system = new System;
$system->loadClass('db', 'database');
?>
It's working.. But I need to access all methods (and instances) of loaded class from any loaded class like this:
<?php
class System {
public function loadClass($instance, $name)
{
$this->$instance = new $name;
}
public function run()
{
echo $this->subA->methodA();
echo $this->subB->methodB();
}
}
class subClassA extends System {
function __construct()
{
echo $this->subB->methodB();
}
public function methodA()
{
return 'okA';
}
}
class subClassB extends System {
function __construct()
{
echo $this->subA->methodA();
}
public function methodB()
{
return 'okB';
}
}
$system = new System;
$system->loadClass('subA', 'subClassA');
$system->loadClass('subB', 'subClassB');
$system->run();
?>
How it is possible without using static methods and instances?
I have this parent class in PHP:
class parentClass{
public $table;
public function __construct(){
$this->table = "my_parent_table";
}
public function getName($id) {
$strQuery = "SELECT name FROM $this->table WHERE id=$id";
$result = mysql_query($strQuery);
if ($result) {
$row = mysql_fetch_object($result);
if ($row) {
return $row->name;
} else {
return false;
}
} else {
return false;
}
}
}
And I have also another class with inherits this one:
class childClass extends parentClass{
public $table;
public function __construct(){
$this->table = "my_child_table";
}
}
Then in another file I am doing:
$myObj = new childClass();
$name = $myObj->getName('1');
The problem now is that the getName function has a null table, so the variable $this->table is null, while I want it to be ""my_child_table" as long as I have a childClass object.
Does anyone know what I am doing wrong?
Thanks in advance
Not sure, but this look tricky:
class childClass extends parentClass{
public $table;
The parentClass already defines a $table, so it's likely that redeclaring it inside the child class will clobber the parent's version. You have to remove the declaration here. Also, public visibility doesn't really encapsulate the state very well; use protected in the parent instead.
public function __construct()
{
You should add parent::__construct() here (unless parent only sets $this->table, but even then it's good to add)
$this->table = "my_child_table";
}
}
I added in parent::__construct(); to the constructors of table and bookmark in order to get this code to work. Why are they not called automatically?
If I create an object of type bookmark $obj_ref_bo = new bookmark(); should not bookmark also create objects from each of its parent classes (besides abstract classes).
The call chain is
bookmark->table->database(abstract)->single_connect
/*single_connect*/
class single_connect
{
protected static $_db_pointer = NULL;
private function __construct()
{
$this->_db_pointer = mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_select_db(DB_DATABASE);
}
public static function get_connection()
{
if(self::$_db_pointer == NULL)
{
return new self();
}
else
{
echo "Error:only one connection";
}
}
}
/*database*/
abstract class database
{
protected function __construct()
{
single_connect::get_connection();
}
static protected function query($query)
{
$result = mysql_query($query) or die(mysql_error());
return $result;
}
}
/*table*/
class table extends database
{
public $_protected_arr=array();
protected function __construct()
{
parent::__construct();
$this->protect();
}
protected function protect()
{
foreach($_POST as $key => $value)
{
$this->_protected_arr[$key] = mysql_real_escape_string($value);
}
}
}
/*bookmark*/
class bookmark extends table
{
function __construct()
{
parent::__construct();
$this->start();
}
function start()
{
if(this->test())
{
this->insert();
}
else
{
return 1;
}
}
function test()
{
if(this->test_empty())
{
return 1;
}
else
{
return 0;
}
}
function test_empty()
{
if(text::test_empty($this->_protected_arr))
{
return 1;
}
else
{
return 0;
}
}
function insert()
{
$url = $this->_protected_arr['url'];
$title = $this->_protected_arr['title'];
$email = $_SESSION['email'];
database::query("INSERT INTO bo VALUES ('$title', '$url', '$email')");
}
}
should not bookmark also create objects from each of its parent classes
That's entirely your choice to make, there is no requirement in the language to call the parent methods.
As the PHP manual concisely puts it:
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required.
— http://php.net/oop5.decon
While Java will call the no-arg constructor of the parent class if you don't call one specifically, PHP has no such feature. This allows you to do some work before calling the parent constructor, though you obviously shouldn't depend on any properties set by the parent constructor. ;)
BTW, as I stated in a comment, most of your calls that use self:: should be using $this-> instead. Only static methods are called using self::.
I want to have a static method in a parent class that creates instances of whatever subclass i call this method on.
An example to make this more clear:
class parent {
public static method make_objects($conditions){
for (...){
// here i want to create an instance
// of whatever subclass i am calling make_objects on
// based on certain $conditions
}
}
}
class sub extends parent{
...
}
$objects = sub::make_objects($some_conditions);
As of php 5.3 you can use the static keyword for this
<?php
class A {
public static function newInstance() {
$rv = new static();
return $rv;
}
}
class B extends A { }
class C extends B { }
$o = A::newInstance(); var_dump($o);
$o = B::newInstance(); var_dump($o);
$o = C::newInstance(); var_dump($o);
prints
object(A)#1 (0) {
}
object(B)#2 (0) {
}
object(C)#1 (0) {
}
edit: another (similar) example
<?php
class A {
public static function newInstance() {
$rv = new static();
return $rv;
}
public function __construct() { echo " A::__construct\n"; }
}
class B extends A {
public function __construct() { echo " B::__construct\n"; }
}
class C extends B {
public function __construct() { echo " C::__construct\n"; }
}
$types = array('A', 'B', 'C');
foreach( $types as $t ) {
echo 't=', $t, "\n";
$o = $t::newInstance();
echo ' type of o=', get_class($o), "\n";
}
prints
t=A
A::__construct
type of o=A
t=B
B::__construct
type of o=B
t=C
C::__construct
type of o=C
I think you want something like this:
class parent {
public static function make_object($conditionns) {
if($conditions == "case1") {
return new sub();
}
}
}
class sub extends parent {
}
Now you can create an instance like this:
$instance = parent::make_object("case1");
or
$instance = sub::make_object("case1");
But why would you want all the sub classes to extend the parent? Shouldn't you much rather have a parent for your models (sub classes) and then a factory class, that creates the instances for this models depending on the conditions given?
Umm, wouldn't that be:
class sub extends parent {
public static function make_objects($conditions) {
//sub specific stuff here
//....
}
}
make the parent class an abstract class and make the parent method also an abstract
abstract static class parent {
abstract function make_method() {
// your process
}
}
class child extends parent {
public function __construct() {
parent::make_method();
}
}