Can someone explain me and make some example for a static and non static class that works together?
like:
App::MySQL()->insert();
App::User()->name;
i can't find anything on web.
Thanks
The first part (e.g. App::MySQL(), App::User()) is calling a static method on a class in order to return a singleton instance (meaning if an instance of that class exists return it, else create a new one and return it), this makes sure that you have at most one instance of that class. Then you call its methods or get its properties (the second part: ->insert(), ->name)
<?php
class App {
public static function MySQL() {
return new MySQL();
}
}
class MySQL {
public function insert() {
echo "inserting some stuff\n";
}
}
App::MySQL()->insert();
gives
ivo#atmycomputer ~$ php test.php
inserting some stuff
ivo#atmycomputer ~$
Related
I want to call a static method from a variabe class in PHP. As pointed out several times on SO and because it is general practice, the following works as expected:
class Foo {
public function compile($strClass) {
$strClass::find(); // this works
}
}
Nonetheless I have to call different find methods from $strClass from different methods of a class Foo. That is, why I want to store $strClass in $this->strClass. Unfortunately, this doesn't work:
class Foo {
protected $strClass;
public function __construct($strClass)
{
$this->strClass = $strClass;
}
public function compile($strClass) {
$this->strClass::find(); // this does not work
}
}
Any idea or hint on how to solve that issue?
Update:
As pointed out in the comments, it might be a solution to use call_user_func like this:
call_user_func(array($this->strClass, 'find'), $strParam);
Anyhow, this makes code completion in PHPstorm impossible. Any hints on that? Maybe using code annotation?
You can change your compile method to this:
public function compile($strClass) {
call_user_func(array($this->strClass, 'find'));
}
This class design is flawed. I would try to get rid of the static methods completely, but here is a solution that exploits the fact that you can call static methods on objects:
class Foo {
protected $strClass;
public function __construct($strClass)
{
$this->strClass = new $strClass;
}
public function compile($strClass) {
$this->strClass::find();
}
}
UPDATE: nevermind, this is a syntax error in all current PHP versions, you actually have to do it like this:
$strClass = $this->strClass;
$strClass::find();
And this works with your original code as well, where $this->strClass is a string.
I have seen in Laravel calling multiple method in the single line, example:
DB::get('test')->toJson();
I have a cool class and view method in that class.
$this->call->view('welcome')->anotherMethod();
I would like to call another method also? Where should I make that method?
DB::get() seems to be a method returning an object, where you can call other functions (I think a result object of a database query). If you want to call multiple functions on one object in one line, you have to return $this in your functions, e.g.:
class View {
public static function factory {
// The question is: How useful is this factory function. In fact: useless in
// the current state, but it can be extended in any way
return new self;
}
public function one() {
// do something
return $this;
}
public function two() {
// do something
return $this;
}
}
Then you can do:
$class = new View();
$class->one()->two();
// it's also possible to use the `factory` function
// you should think about, how useful this approach is in your application
$class = View::factory()->one()->two();
That's how you can do it in php, if laravel has some helpers for that, i can't say :)
Second update
I think I've been approaching this problem from the wrong side of the coin. Would I be correct in assuming that I should be making 'First' an abstract class and just finding a way to reference 'Second' and 'Third' at a later time?
Update
Based on some of the feedback, I have added some content to try and clear up what I would like to do. Something similar to this effect.
I know from just looking at the code below that, it is a waste of performance "if" it did work and because it doesn't, know I am approaching the problem from the wrong angle.The end objective isn't all to uncommon at a guess from some of the frameworks I've used.
I'm more trying to base this particular bit of code on the CodeIgniter approach where you can define (what below) is STR_CLASS_NAME in a config file and then at any point through the operation of the program, use it as i have dictated.
STR_CLASS_NAME = 'Second';
class First {
protected $intTestOne = 100;
public function __construct() {
$strClassName = STR_CLASS_NAME;
return new $strClassName();
}
public function TestOne() {
echo $this->intTestOne;
}
protected function TestThreePart() {
return '*Drum ';
}
}
class Second extends First{
/* Override value to know it's working */
protected $intTestOne = 200;
/* Overriding construct to avoid infinite loop */
public function __construct() {}
public function TestTwo() {
echo 'Using method from extended class';
}
public function TestThree() {
echo $this->TestThreePart().'roll*';
}
}
$Test = new First();
$Test->TestOne(); <-- Should echo 200.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum roll*'
You may be asking, why do this and not just instantiate Second, well, there are cases when it is slightly different:
STR_CLASS_NAME = 'Third';
class Third extends First{
/* Override value to know it's working */
protected $intTestOne = 300;
/* Overriding construct to avoid infinite loop */
public function __construct() {}
public function TestTwo() {
echo 'Using method from extended class';
}
public function TestThree() {
echo $this->TestThreePart().'snare*';
}
}
$Test = new First();
$Test->TestOne(); <-- Should echo 300.
$Test->TestTwo(); <-- Should echo 'Using method from extended class'
$Test->TestThree(); <-- Should echo '*Drum snare*'
Situation
I have a an abstract class which extends a base class with the actually implementation; in this case a basic DB wrapper.
class DBConnector ()
class DBConnectorMySQLi extends DBConnector()
As you can see, MySQLi is the implementation. Now, dependant upon a value in the configuration process, a constant becomes the class name I wish to use which in this case (as shown below builds DBConnectorMySQLi.
define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);
Objective
To have a base class that can be extended to include the implementation
For the code itself not to need know what the name of the implementation actually is
To (in this case) be able to type or use a project accepted common variable to create DBConnectorMySQLi. I.E. $db or something similar. W
Issue
When it comes to actually calling this class, I would like the code to be shown as below. I was wondering whether this is at all possible without the need to add any extra syntax. On a side note, this constant is 100% guaranteed to be defined.
$DBI = new DB_CLASS();
Solution 1
I know it is possible to use a reflection class ( as discussed in THIS QUESTION) and this works via:
$DBI = new ReflectionClass(DB_CLASS);
However, this creates code that is "dirtier" than intended
Solution 2
Start the specific implementation of DBConnectorMySQLi within the constructor function of DBConnector.
define('STR_DB_INTERFACE', 'MySQLi');
define('DB_CLASS', 'DBConnector'.STR_DB_INTERFACE);
class DBConnector() { public function __construct() { $this->objInterface = new DBConnectorMySQLi(); }
class DBConnectorMySQLi()
This however would result in the need to keep on "pushing" variables from one to the other
Any advice is much appreciate
You can use variables when you instantiate a class.
$classname = DB_CLASS;
$DBI = new $classname();
Source: instantiate a class from a variable in PHP?
I tried these two ways:
(new NewsForm())->getWidgetSchema();
{new NewsForm()}->getWidgetSchema();
With no luck...
PHP does not allow you to do this. Try:
function giveback($class)
{
return $class;
}
giveback(new NewsForm())->getWidgetSchema();
It is a rather weird quirk with the language.
You can't an instanciation and a method call in one instruction... But a way to "cheat" is to create a function that returns an instance of the class you're working with -- and, then, call a method on that function which returns an object :
function my_function() {
return new MyClass();
}
my_function()->myMethod();
And, in this kind of situation, there is a useful trick : names of classes and names of functions don't belong to the same namespace -- which means you can have a class and a function that have the same name : they won't conflict !
So, you can create a function which has the same name as your class, instanciates it, and returns that instance :
class MyClass {
public function myMethod() {
echo 'glop';
}
}
function MyClass() {
return new MyClass();
}
MyClass()->myMethod();
(Yeah, the name of the function is not that pretty, in this example -- but you see the point ;-) )
If it is a static method you can just do this:
NewsForm::getWidgetSchema();
A better option in my opinion would be to use a factory method:
class factory_demo {
public static function factory()
{
return new self;
}
public function getWidgetSchema()
{ }
}
then
factory_demo::factory()->getWidgetSchema()
Of course, you get all the benefits of the factory pattern as well. Unfortunately this only works if you have access to the code, and are willing to change it.
I have created a PHP class called formChecker.php. It validates a form. As a Java programmer, I would like to stick with the idea of creating an instance of this class in another class and run it from there. It doesn't seem to be working for me.The following is a demonstration:
class formChecker{
..... validation functions go here
}
class runFormChecker{
.... create instance of formchecker here and use it's methods etc.
}
Can this be done? What I'm thinking of is developing a number of classes that can be run seperately.
GF
I'd rather pass the instance of formChecker (or something that implements a certain interface) to the instance of runFormChecker. see http://en.wikipedia.org/wiki/Dependency_injection
Could be as simple as
interface FormChecker {
public function foo($x);
}
class MyFormChecker implements FormChecker
public function foo($x) {
return true;
}
}
class RunFormChecker {
protected $formChecker=null;
public function __construct(FormChecker $fc) {
$this->formChecker = $fc;
}
// ....
}
$rfc = new RunFormChecker(new MyFormChecker);
Just include the formChecker class file just before the class you want to use it in eg:
include "formChecker.php"
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
If however, you have both classes in one file (which is bad), then no need to include the file, you can create the instance of that straight away eg:
class formChecker{
// ............
}
class runFormChecker{
function __construct() {
$obj = new formChecker; // create instance
// more processing............
}
}
More Information Here....
Thanks :)
Yes, and this is not strange. You would usually create the instance of formChecker within an instance of runFormChecker though, and not at the class level.