<?php
class DBFactory {
function __construct(){
return 'Need to echo';
}
}
$db = new DBFactory;
echo $db;
?>
Not works :(
I dont understand why your looking into OOP if your tryiung to return values on a constructor.
the whole point of OOP is to have objects that perform many tasks, if you want to return a string,array,resource then OOP is not for you.
__constructors are used to initiate code during the pre stages of the object initialization, witch allows you to execute code to prepare an object before the user can use it.
If you wish to use the __toString on objects then use it wisely, its main perpose is for a readability factor in objects, not storage etc. mainly used in error debugging.
When you create an object using the new keyword php's processor creates an object and assigns it to the memory, it then runs the construct but does not hold any returned values from it, after the constructor as reached its endppoint, the link for the object in the memory is returned to the variable you asked it to be. so in theory you can run $db->__construct() as its still a method, but only after the object is fully created.
just create a method to return a string like so
class DBFactory
{
function whatAmI()
{
return 'I am DBFactory';
}
}
$MyOBJECT = new DBFactory;
echo $MyOBJECT->whatAmI();
This is REALLY REALLY Stupid to do but as you wish to know how,
class DBFactory{
function __construct()
{
return 'Need to echo';
}
}
$db = new DBFactory();
echo $db->__construct();
You cannot return anything from the constructor. You're already getting a new object back, you can't get another value on top of that and assign both to $db.
The constructors should not return anything.
If you want to echo an object, you have to define how to form its string representation with the magic method __tostring:
class DBFactory {
function __tostring(){
return 'Need to echo';
}
}
$db = new DBFactory();
echo $db;
Generally it's not possible to return a value in a constructor of a class. In this case, $db contains the instance of the class, not the return value.
You could build a separate function, and have that function return the value:
<?php
class DBFactory {
function toEcho() {
return 'Need to echo';
}
}
$db = new DBFactory();
echo $db->toEcho();
?>
$db = new DBFactory();
i think this "()" also be here
You could use the __toString magic method to get __construct to echo out
or you could just getmetod without using __toString magic method. There are many ways just pick one of them.
<?php
// Declare a simple class
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
__toString()
Related
I am interested in how this works:
<?php
$Query = $mysqli->query("select * from table");
$Query->fetch_array(); // <== How to make $Query a class/method like this?
?>
How do you assign a method to a variable and then have that variable be able to call another method like the $mysqli and $Query example above?
One way to achieve what you are (I think) referring to, is by returning an object. It goes against the principle of dependency injection, but it's one way to do it.
class MyClassA
{
public function myFunction()
{
return new MyClassB();
}
}
class MyClassB
{
public function execute()
{
return true;
}
}
// Start use
$class = new MyClassA();
// Assign variable to function which returns object
$newObj = $class->myFunction();
// Will write "1" because now $newObj is MyClassB()
echo $newObj->execute();
Another way is to return $this from the first method. The usage of the above object would work identical in this instance, however you also allow another principle known as method chaining:
class MyClassA
{
public function myFunction()
{
return $this;
}
public function execute()
{
return true;
}
}
// Same as above works
$class = new MyClassA();
$sameObj = $class->myFunction();
echo $sameObj->execute();
// Allowing for Method Chain
$class = new MyClassA();
// Allowing for chaining
echo $class->myFunction()->execute();
You have to instantiate your class and call it's function with ->
$class = new MyClass(); // Instantiate class
$class->myFunction(); // Use it's function
PHP manual example of creating a class:
http://php.net/manual/en/language.oop5.basic.php
$str = "$obj = new class(); $obj->getSomeFunction();"
Is this possible? I am trying to develop a very dynamic platform to base my website off of.
Anyway to get this working? From a string by "echo $str;" it will make the object and run the function?
Instead of passing an object as a string, just create a new instance of your object. And once you've included a file.. All variables, objects, etc. exist in the file that includes that file.
Edit:
Instead of passing a class as a string, you can create classes dynamically:
<?php
class cc {
function __construct() {
echo 'hi!';
}
}
$type = 'cc';
$obj = new $type; // outputs "hi!"
?>
Alternatively you can use static classes:
<?php
class Foo {
public static function aStaticMethod() {
echo 'hi!';
}
}
Foo::aStaticMethod(); // outputs "hi!"
// or:
$classname = 'Foo';
$classname::aStaticMethod(); // outputs "hi!"
?>
I am in the process of writing my own mvc framework(as an learning project), and needed to dynamically create objects and call a method. I ended up using the reflection api in order to create a new instance of the object and then call the method. in this case i ended up passing an associative array that had two key/value pairs, the class name, and the method I wanted to call. I hope this helps.
$class = $command['class'];
$method = $command['method'];
try{
$reflectorClass = new ReflectionClass($class);
$reflectedInstance = $reflectorClass->newInstance($matches);
} catch (Exception $e) {
exceptionHandler::catchException($e);
}
try {
$reflectorMethod = new ReflectionMethod($reflectedInstance, $method);
$reflectorMethod->invoke($reflectedInstance);
} catch (Exception $e) {
exceptionHandler::catchException($e);
}
In PHP included files are executed when you call include() or require(). They follow variable scope rules and even allow you to return results as if the include was a function like so:
dynamicPlatform.php
<?php
$object = include('createObjAndDoStuff.php');
?>
createObjAndDoStuff.php
<?php
$obj = new class();
$obj->getSomeFunction();
return $obj;
?>
As #zerkms has pointed out, you probably should be using factories.
class Factory {
public static function someclass() {
include_once('./classes/someclass.php'); //Although some discourage the use of *_once() functions
$obj = new someclass();
$obj->getSomeFunction();
return $obj;
}
}
//And to get a new class instance
$object = Singleton::someclass();
Or pseudo-singletons with factories:
class SingletonFactory {
private static $someclass;
public static function someclass() {
if(!self::$someclass) {
include('./classes/someclass.php');
self::$someclass = new someclass();
self::$someclass->getSomeFunction();
}
return self::$someclass;
}
}
What you are searching for is eval but while it will do exactly what you are asking for, it's considered bad solution and can lead to messy code.
You can just include file that contains PHP code, or you can serialize meta data about the actions to be performed and then parse that data.
Depending on what you are trying to achieve, you may be interested in serializing objects in session as well as in Command Pattern (a way to encapsulate set of operations in object(s))
Is it possible to add methods to functions?
For example:
<?
function func(){
;
}
//add method
func->test = function(){
;
}
func->test();
func();
I'm coming from a javascript background, and therefore I'm used to 'everything is an object'.
EDIT:
I was just explaining where the misconception may often come from for new phpers. I understand the above code doesn't work.
EDIT 2
Figured it out.
class myfunc_class{
function __invoke(){
//function body
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new myfunc_class;
$func->test = function(){
echo '<br>test<br>';
};
$func->test();
$func();
Even sexier :)
class func{
public $_function;
function __invoke(){
return call_user_func_array($this->_function,func_get_args());
}
function __construct($fun){
$this->_function = $fun;
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new func(function($value){
echo $value;
});
$func->method = function(){
echo '<br>test<br>';
};
$func('someValue');
$func->method();
No.
Not everything is an object in PHP. In fact the only thing that is an object is, well, an object. More specifically, and generally, an instantiation of a class.
Your code converted to PHP
// function_object.php
<?php
class FunctionObject {
public method func() {
// do stuff
}
}
?>
In other code you would use it like this:
<?php
// example.php in same folder as function_object.php
include 'function_object.php';
$FuncObj = new FunctionObject;
$FuncObj->func();
Also: read more about PHP & OOP
No, because an object is a different PHP language construct than a function. Functions do not have properties, but are instead simply execution instructions.
But, if func were instead a pre-defined class, then yes... with a bit of witchcraft, ignoring public outcry, foregoing readability and PHP coding standards, and by using closures with the __call() magic method...
class func
{
function __call($func, $args)
{
return call_user_func_array($this->$func, $args);
}
}
$obj = new func;
$obj->test = function($param1, $param2)
{
return $param1 + $param2;
};
echo $obj->test(1,1);
This won't work as you'd think without __call(), because by $obj->test(1,1), PHP thinks you're trying to call a non-existent method of func when out of object scope. But inside, being that the new "test" property is of a type: closure, the call_user_func_array() just sees the "test" property as just another function, so you can hide this bit of trickery from outside scope.
You would need your function func() to return an object, then you'd be able to do something like: func()->test();
But please note that your way of handling objects is not right in PHP and I suggest that you go read the OO documentations here.
In difference to javacript, in PHP not everything is an object. Therefore you need to differ between function and class.
If you want to create an object, you need to define the class first.
class myClass {
}
You can then add as many functions to the class as you need. But you need to define them first:
class myClass {
function test() {
echo "test!\n";
}
}
When everything is ready, you can bring it to life then:
$class = new myClass;
$class->test();
Checkout the manual for more.
You can't do what you're trying to do, but you can define functions inside of other functions.
This example outputs text:
function a() {
function b() { echo 'Hi'; }
}
a();
b();
Output: HiHi
This example outputs an error:
function a() {
function b() { echo 'Hi'; }
}
b();
Output: ERROR
Hey, I have a small test case set up as following:
class T {
public function __construct(){
$obj = new SimpleXMLElement(file_get_contents('vote.xml'));
return $obj;
}
}
$vv=new T;
var_dump($vv);
The dump of $vv equals, in this case, object(T)#1 (0) { } - in other words, not the expected output
When I return the object in a separate function, though, like this:
class T {
public function stackOverflow(){
$obj = new SimpleXMLElement(file_get_contents('vote.xml')); // or simplexml_load_file
return $obj;
}
}
$vv=new T;
$vv = $vv->stackOverflow();
var_dump($vv);
output is as expected (the object containing contents of 'vote.xml', tags and attributes). Why can I not return the object inside of the constructor? Thanks!
The constructor will only ever return a reference to the newly created object. This is intentional -- how else would you get a reference to the new object?
You could, however, create an object property in your constructor and then access it from outside. This would mean that you would create the object during the constructor process, so it would be done at the right time and, what's more, could be guaranteed to be done.
class T {
public $sxml;
public function __construct(){
$this->sxml = new SimpleXMLElement(file_get_contents('vote.xml'));
}
}
$vv=new T;
var_dump($vv->sxml);
Of course, if you don't need the reference to the new object, you could use a static method instead and never use the constructor:
class T {
public static function sxml() {
return new SimpleXMLElement(file_get_contents('vote.xml'));
}
}
I want to access private methods and variables from outside the classes in very rare specific cases.
I've seen that this is not be possible although introspection is used.
The specific case is the next one:
I would like to have something like this:
class Console
{
final public static function run() {
while (TRUE != FALSE) {
echo "\n> ";
$command = trim(fgets(STDIN));
switch ($command) {
case 'exit':
case 'q':
case 'quit':
echo "OK+\n";
return;
default:
ob_start();
eval($command);
$out = ob_get_contents();
ob_end_clean();
print("Command: $command");
print("Output:\n$out");
break;
}
}
}
}
This method should be able to be injected in the code like this:
Class Demo
{
private $a;
final public function myMethod()
{
// some code
Console::run();
// some other code
}
final public function myPublicMethod()
{
return "I can run through eval()";
}
private function myPrivateMethod()
{
return "I cannot run through eval()";
}
}
(this is just one simplification. the real one goes through a socket, and implement a bunch of more things...)
So...
If you instantiate the class Demo and you call $demo->myMethod(), you'll get a console: that console can access the first method writing a command like:
> $this->myPublicMethod();
But you cannot run successfully the second one:
> $this->myPrivateMethod();
Do any of you have any idea, or if there is any library for PHP that allows you to do this?
Thanks a lot!
Just make the method public. But if you want to get tricky you can try this (PHP 5.3):
class LockedGate
{
private function open()
{
return 'how did you get in here?!!';
}
}
$object = new LockedGate();
$reflector = new ReflectionObject($object);
$method = $reflector->getMethod('open');
$method->setAccessible(true);
echo $method->invoke($object);
EDIT:
Updated to include examples of private function calls with parameters.
As of PHP 5.4, you can use the predefined Closure class to bind a method/property of a class to a delta functions that has access even to private members.
The Closure class
For example we have a class with a private variable and we want to access it outside the class:
class Foo {
private $bar = "Foo::Bar";
private function add_ab($a, $b) {
return $a + $b;
}
}
PHP 5.4+
$foo = new Foo;
// Single variable example
$getFooBarCallback = function() {
return $this->bar;
};
$getFooBar = $getFooBarCallback->bindTo($foo, 'Foo');
echo $getFooBar(); // Prints Foo::Bar
// Function call with parameters example
$getFooAddABCallback = function() {
// As of PHP 5.6 we can use $this->fn(...func_get_args()) instead of call_user_func_array
return call_user_func_array(array($this, 'add_ab'), func_get_args());
};
$getFooAddAB = $getFooAddABCallback->bindTo($foo, 'Foo');
echo $getFooAddAB(33, 6); // Prints 39
As of PHP 7, you can use the new Closure::call method, to bind any method/property of an obect to a callback function, even for private members:
PHP 7+
$foo = new Foo;
// Single variable example
$getFooBar = function() {
return $this->bar;
};
echo $getFooBar->call($foo); // Prints Foo::Bar
// Function call with parameters example
$getFooAddAB = function() {
return $this->add_ab(...func_get_args());
};
echo $getFooAddAB->call($foo, 33, 6); // Prints 39
The first question you should ask is, if you need to access it from outside the class, why did you declare it private? If it's not your code, the originator probably had a good reason to declare it private, and accessing it directly is a very bad (and largely unmaintainable) practice.
EDIT: As Adam V. points out in the comments, you need to make the private method accessible before invoking it. Code sample updated to include this. I haven't tested it, though - just adding here to keep the answer updated.
That having been said, you can use Reflection to accomplish this. Instantiate ReflectionClass, call getMethod for the method you want to invoke, and then call invoke on the returned ReflectionMethod.
A code sample (though I haven't tested it, so there may be errors) might look like
$demo = new Demo();
$reflection_class = new ReflectionClass("Demo");
$reflection_method = $reflection_class->getMethod("myPrivateMethod");
$reflection_method->setAccessible(true);
$result = $reflection_method->invoke($demo, NULL);
Here's a variation of the other answers that can be used to make such calls one line:
public function callPrivateMethod($object, $methodName)
{
$reflectionClass = new \ReflectionClass($object);
$reflectionMethod = $reflectionClass->getMethod($methodName);
$reflectionMethod->setAccessible(true);
$params = array_slice(func_get_args(), 2); //get all the parameters after $methodName
return $reflectionMethod->invokeArgs($object, $params);
}
I have these problems too sometimes, however I get around it through my coding standards. Private or protected functions are denoted with a prefix underscore ie
private function _myPrivateMethod()
Then i simply make the function public.
public function _myPrivateMethod()
So although the function is public the naming convention gives the notification that whilst public is is private and shouldn't really be used.
If you are able to added a method in the class where the method is defined, you can add method which uses the call_user_method() internally. This works also with PHP 5.2.x
<?php
class SomeClass {
public function callprivate($methodName) {
call_user_method(array($this, $methodName));
}
private function somePrivateMethod() {
echo 'test';
}
}
$object = new SomeClass();
$object->callprivate('somePrivateMethod');
Answer is put public to the method. Whatever trick you are going to do it wouldn't be understandable to fellow developers. For example they do not know that at some other code this function has been accessed as public by looking at the Demo class.
One more thing. that console can access the first method writing a command like:. How can this even be possible? Console can not access demo class functions by using $this.
I guess the reflectionClass is the only alternative if you really want to execute some private methods. Anyhow, if you just need read access to privat or protected properties, you could use this code:
<?php
class Demo
{
private $foo = "bar";
}
$demo = new Demo();
// Will return an object with public, private and protected properties in public scope.
$properties = json_decode(preg_replace('/\\\\u([0-9a-f]{4})|'.get_class($demo).'/i', '', json_encode((array) $demo)));
?>
<?php
$request="email";
$data=[1,2,3,4,5];
$name=new Update($request,$data);
class Update{
private $request;
private $data;
function __construct($request,$data){
$this->request=$request;
$this->data=$data;
if($this->request=='email'){
$this->update_email();
}
else{
echo "Can't do anything";
}
}
private function update_email(){
echo $this->request;
echo '\n';
foreach($this->data as $x){
echo $x."\n";
}
}
}
?>