After 9 hours of struggling to get this right, I have turned to the internet for help. I can't seem to find any relevant answers doing a Google search.
I currently have a class called Test. Test accepts a single argument.
<?php
class test {
private $varpassed;
public function getVarpas() {
return $this->varpassed;
}
Public function setVarpas($value) {
$this->varpassed= $value;
}
public function stringGen(){
$testvar = $this->varpassed;
echo $testvar;
}
}
The stringGen function should return the $varpassed variable whenever its called. The value for $varpassed is set using the setVarpas function. However, when ever I call the stringGen() method I only seem to be getting the following error:
Fatal error: Using $this when not in object context in file.php line 14.
Pointing to this line:
$testvar = $this->varpassed;
Is there any other way to pass the variable to the stringGen method? I've tried using:
self::$this->varpassed;
Which also throws an error.
first create an instance of the object (so you can use $this in the context), for example:
$test = new test();
then you can call:
$test->setVarpas('Hello World!');
now you can call:
$test->stringGen();
you have to do something like this
$var = new test();
$var->setVarpas("Hello");
$var->stringGen(); // this will echo Hello
$this is used when you are withing class. outside class you have to use class object.
1) Change this: class test() to class test
2) Create and instance first something like $t1 = new test();
3) Call the function $t1->setVarpas(5);
4) Now you can call the function $t1->stringGen();
Fixed:
<?php
class test
{
private $varpassed;
public function getVarpas() {
return $this->varpassed;
}
Public function setVarpas($value) {
$this->varpassed= $value;
}
public function stringGen(){
$testvar = $this->varpassed;
echo $testvar;
}
}
$t1 = new test();
$t1->setVarpas(5);
$t1->stringGen();
OUTPUT:
5
You should not declare a class with parentheses.
Use
class test {
instead of
class test(){
Related
I have a function inside a function and the inner function cannot find the outer class. I don't know why. I hope someone has an idea how I can solve this. I don't want to declare the inner function outside of the outer function.
class Foo {
public $test = "test123";
private function outerfunction(){
function innerfunction(){
echo $this->test;
}
innerfunction();
}
}
if I call the inner function I get the error Using $this when not in object context.
just restructure it to an anonymous function:
$innerfunction = function () {
echo $this->test;
}
$innerfunction();
The class context is then automatically bound to the function (see also http://php.net/manual/en/functions.anonymous.php)
Be aware, that this only works for >= PHP 5.4
You have to declare it as a variable, or it will tell you that you aren't in an object context:
$innerfunction = function() {
echo $this->test;
};
call_user_func($innerfunction);
Alternatively, you can keep the function as you do, and pass it the object context since it's known at the call point:
function innerfunction(/* Foo */ $obj) {
echo $obj->test;
};
innerfunction($this);
The most glaring issue with this approach is that calling outerFunction() more than once will produce:
Fatal error: Cannot redeclare innerfunction()...
Another issue is that innerfunction() is declared in the global scope. If this is intentional then that is highly unconventional and you probably should not do that. Anyways, it allows for this:
class Foo {
public $test = "test123";
public function outerfunction(){
function innerfunction(){
//echo $this->test;
}
innerfunction();
}
}
$a = new foo();
// innerfunction(); // NOPE!
$a->outerFunction();
innerfunction(); // YES
So, this is the logical way to declare innerfunction():
class Foo {
public $test = "test123";
public function outerfunction(){
$this->innerfunction();
}
private function innerfunction(){
echo $this->test;
}
}
$a = new foo();
$a->outerFunction();
I have a class and I am including the players.php file inside it.
class My_Class {
private $player_types;
public function __construct() {
$this->player_types = 'classic';
require_once('players.php');
}
public function getPlayerTypes() {
return $this->player_types;
}
}
$mc = new My_Class();
How can I call getPlayerTypes function from players.php?
Also if its better to maybe use static method?
Just write :
$result = $this->getPlayerTypes();
echo $result;
inside the players.php. Definitely this will work.
Since the getPlayerTypes() is a method defined in the class My_Class, if you want to call that method from players.php you should instantiate a new My_Class object in that file and call the getPlayerTypes() there.
//player.php
$mc = new My_Class();
$playerTypes = $mc->getPlayerTypes();
echo $playerTypes
and remove that
require_once('players.php');
from your class :)
Since you are instantiating the class with the variable $mc, you'd call the function using
$mc->getPlayerTypes();
Or you can assign a variable to the result,
$result = $mc->getPlayerTypes();
echo $result;
I know it isn't actually the reverse engineering
I have this function:
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
I want to understand how to insert a function (using include maybe) that gets called when using that code.
I know the function name needs to be trans, and it has 3 arguments, but how to define it? Let me put this in a more easy way: In a php script how do I print Hello world when using $this->get('translator')->trans('dashboard.actions', array(), 'front');
It's just a regular class method:
class Traslator{
public function trans($a, $b, $c){
return 'Hello world';
}
}
Now, you only need another class method called get() that returns an instance of the previous class:
class Foo{
public function get(){
return new Traslator;
}
}
Full code:
<?php
class Traslator{
public function trans($a, $b, $c){
return 'Hello world';
}
}
class Foo{
public function get(){
return new Traslator;
}
public function test(){
?>
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
<?php
}
}
$f = new Foo;
$f->test();
$this references the current object instance, and that variable may not be re-assigned. Meaning, to trick PHP into doing what you want requires to add code before and after the line you mention.
By creating a single class, the result can be obtained.
Before the <?=... line
<?php
class C {
function get($s) {
return $this;
}
function trans($s, $a, $f) {
return 'Hello world';
}
function hw() {
?>
Then the line
<?=$this->get('translator')->trans('dashboard.actions', array(), 'front');?>
Then need, to end the class, and call the method that does what you want
<?php
}}
$i = new C();
$i->hw();
Put the 3 blocks of code into a file and call PHP on it, the <?=... line should show "Hello world".
$this->get('translator') return instance of class lets call it "Translator" - on that instance you call trans() method
so you would like to change instance of "Translator" to your extended version
class ExtTranslator extends Translator{
public function trans($params){
echo 'fdsfds'; // here you could add what you like
return parent::trans($params);
}
}
and yes - it's hard to help you cause I don't really know what are you trying to do - to work with that code you must first understand it...
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";
}
}
}
?>
I'm fairly new to PHP so I have a small problem as I'm learning:
I built a Class called DataStrip.php
<?php
final class DataStrip
{
public function DataStrip()
{
// constructor
}
public function stripVars($vars)
{
return $vars;
}
}
?>
and then I'm trying to pass the public function stripVars a value:
<?php
include_once ('lib/php/com/DataStrip.php');
echo($projCat);
$a = new DataStrip;
$a->stripVars($projCat);
echo($a);
?>
however, I get back this error:
( ! ) Catchable fatal error: Object of class DataStrip could not be converted to string in myfilepath
... any advice perhaps on what I could be doing wrong here? Right now this is just a test function as I'm trying to get used to OOP PHP. :)
What do you expect it to happen? You're not saving the result of what stripVars returns into a variable:
$result = $a->stripVars($projCat);
print $result;
What you are trying to do is print the object variable itself. If you want to control what happens when you try to print an object, you need to define the __toString method.
if you want to do that... you need declarate the method __toString()
<?php
final class DataStrip
{
private $vars;
public function DataStrip()
{
// constructor
}
public function stripVars($vars)
{
$this->vars = $vars;
}
public function __toString() {
return (string) $this->vars;
}
}
// then you can do
$a = new DataStrip;
$a->stripVars($projCat);
echo($a);
?>
Shouldn't you return to a variable:
$projCat = $a->stripVars($projCat);
When you echo $a you're echoing the object - not any particular function or variable inside it (since when you declare $a you're declaring it as everything in the class - variables, functions, the whole kit and kaboodle.
I also have issues with php oop, so please correct if I am wrong :)