i have an issue with function redeclaration problem. So, i am trying to call multiple times this example.
class myClass {
function abc() {
function internal() {
return "i am internal";
}
return internal();
}
}
$myClass = new myClass();
echo $myClass->abc();
echo $myClass->abc(); // HERE IS THE PROBLEM when i call same function second time
PHP showing Fatal error: Cannot redeclare internal() (previously declared).
Does anyone have an idea how can i solve this issue?
Thanks in advance.
You cant redeclare the function period so try something like this:
<?php
class myClass {
function abc() {
return $this->internal();
}
private function internal() {
return "i am internal";
}
}
?>
When you declare a function using function <name>(), you are not declaring it in the scope you think you are. That function is being declared in the class global scope, not the function/class scope.
See the PHP Docs: http://www.php.net/manual/en/functions.user-defined.php#example-149
So, when you call abc, you are re-declaring the global function, internal.
If you want to do what you are doing, you can use closures instead (NOTE: This only works in PHP 5.3+). This has the benefit of being able to read local variables from within abc (if you use the use keyword).
class myClass {
function abc() {
$internal = function() {
return "i am internal";
};
return $internal();
}
}
You can also declare internal as a private function of the class, especially if it's not going to change. Why keep re-making a function?
class myClass {
private function internal(){
return "i am internal";
}
function abc() {
return $this->internal();
}
}
Check whether the function exists prior to defining it:
class myClass {
function abc() {
if ( ! function_exists('internal')) {
function internal() {
return "i am internal";
}
}
return internal();
}
}
Alternatively:
if (!function_exists('internal')) { function internal ... }
However, you have to be aware that in this case, the function internal will be available outside the class scope as well. Lawrence's solution is a better approach.
Related
I'm triyng to convert a normal script in PHP to OO. I'me having some troubles doing that for some things. one of that is call a function (or method) in a variable to use globally.
The initial code is the following:
$myVariable = myFunction();
function myFunction(){
// some code in here
}
I've triyed to do something like following but it doesen't work
class MyClass{
$myVariable = $this->myFunction();
function myFunction(){
// some code in here
}
}
Can someone help me?
You need to call the function in a method (most likely the constructor). if you want to access to the property all over the class definition do this:
// Imagine you have a global method like this
MyFunction() {
}
class MyClass {
// define a property that store the result of calling MyFunction()
protected $somethingThatYouNeed;
// constructor calls when you instantiate your class
public function __construct() {
$this->somethingThatYouNeed = myFunction();
}
public function otherMethod() {
// you can access your variable here by calling $this->somethingThatYouNeed
}
}
I'am trying to make a reference to a static function inside a class:
class Test {
function __construct() {
$this->fn1 = self::fn2;
}
public static function fn2() {
}
}
then i get this error:
Undefined class constant 'fn2'
why?
Not sure if this is what you want, but at least this might give you a hint:
<?php
class Test {
function __construct() {
$this->fn = function(){
return self::realFn();
};
}
public function callFn (){
$fn = $this->fn ;//yes, assigning to a var first is needed. You could also use call_user_func
$fn();
}
public static function realFn() {
echo 'blah';
}
}
$x = new Test();
$x->callFn();
You can test it here: https://3v4l.org/KVohi
You have defined a static function:
Test {
function__construct()
{
$this->fn1 = self::fn2();
}
public static function fn2()
{
}
}
Updated
If you want to assign a function to a variable, it is best to do this
with annonymous aka lambda functions since they are first class citizens and may be freely passed, returned and assigned. PHP is not unique in dealing with static method references in this fashion as JAVA implements them similarly:
Method references ... are compact, easy-to-read lambda expressions for
methods that already have a name.
You may create an anonymous function based on a callable in PHP, and so the OP may wish to do as follows, which PHP 7.1.10 or higher supports:
<?php
class Test {
public static function fn2() {
return __METHOD__;
}
public static function getClosure (){
return Closure::fromCallable(["Test","fn2"]);
}
}
echo Test::getClosure()(),"\n";
See live code here
In this example an anonymous function is created and returned by the static getClosure method. When one invokes this method, then it returns the closure whose content is the same as static method fn2. Next, the returned closure gets invoked which causes the name of static method fn2 to display.
For more info re closures from callables, see the Manual and the RFC.
With PHP 7 on up, you may create a complex callable. In the code below the complex callable is an invocable array:
<?php
class foo
{
public static function test()
{
return [__CLASS__, 'fn2'];
}
public static function fn2()
{
echo __METHOD__;
}
}
echo foo::test()();
See live code.
Note: Starting with PHP 7.0.23 you could create a complex callable using a string containing the class and method names separated by the double colon aka paaamayim nekudotayim; see here.
A solution that has broader PHP support is as follows:
<?php
class Test {
public static function fn2() {
return __METHOD__;
}
public static function tryme(){
return call_user_func(["Test","fn2"]);
}
}
// return closure and execute it
echo Test::tryme();
See live code
I'm trying to use my class inside a function called inside()
I have something like:
class MyClass{
public function test(){ echo "test ok"; }
}
$mc = new MyClass();
function inside(){
global $mc;
$mc->test();
}
But this doesn't work :(
I get:
Fatal error: Call to a member function test() on a non-object in ...
One solution would be to pass the class $mc as an argument to the function inside() but I want something else :/
Any idea ?
Ty guys
Since the inside function depends on the MyClass class, it should be passed in as a dependecy injection.
$mc = new MyClass;
function inside(MyClass $mc){
$mc->test();
}
It looks like you need a refresher of the (Gang of Fours) injection design pattern, http://martinfowler.com/articles/injection.html
If all you want is to access a function residing inside a class you can define it as static
class MyClass {
static function test() {
echo "test ok";
}
}
Then you don't have to use a global:
function inside() {
MyClass::test();
}
You need to define test as public function test(){....
Is there a way to do something like this:
class Test {
if(!empty($somevariable)) {
public function somefunction() {
}
}
}
I know this might not be best practice, but I need to do this for a very specific problem I have, so is there anyway to do it?
I just want that function to be included in the class if that variable (which is tied to a URL param) is not empty. As it is written now, I get Error: syntax error, unexpected T_VARIABLE, expecting T_FUNCTION
Thanks!
It depends on the your specific use case, and I don't have enough info to give a specific answer, but I can think of one possible fix.
Extend the class, using an if statement. Put everything except the one function in AbstractTest.
<?php
abstract class AbstractTest
{
// Rest of your code in here
}
if (!empty($somevariable)) {
class Test extends AbstractTest {
public function somefunction() {
}
}
} else {
class Test extends AbstractTest { }
}
Now, the class Test only has the method somefunction if $somevariable isn't empty. Otherwise it directly extends AbstractTest and doesn't add the new method.
Call the required function if the variable is not empty.
<?php
class Test {
public function myFunct() {
//Function description
}
}
$oTest = new Test();
if(!empty($_GET['urlParam'])) {
oTest->myFunc();
}
?>
class Test {
public function somefunction() {
}
}
is all you need actually.
Please note that a function inside a class is called 'method'.
AFAIK you cannot have a condition out of the method in class scope (if that flows)
Class Test {
if (empty($Var)){
public function Test_Method (){
}
}
}
Will not work. Why not have it constantly exisisting but only call the method when it's needed?
Example:
Class Test {
public function Some_Method(){
return 23094; // Return something for example purpose
}
}
Then from your PHP:
$Var = ""; // set an empty string
$Class = new Test();
if (empty($Var)){
echo $Class->Some_Method(); // Will output if $Var is empty
}
Perhaps you trying to validate a string within OOP scope, then take this example:
Class New_Test {
public $Variable; // Set a public variable
public function Set(){
$This->Variable = "This is not empty"; // When calling, $this->variable will not be empty
}
public function Fail_Safe(){
return "something"; // return a string
}
}
Then out of Scope:
$Class = new New_Test();
if (empty($Class->Variable)){
$Class->Fail_Safe();
} // Call failsafe if the variable in OOP scope is empty
I'm trying to use myVar inside my of a method's function. I have already tried adding global but still nothing. I know this is probably basic but I can't seem to find it.
class myClass{
public $myVar;
public function myFunction() {
function myInnerFunction() {
//how do I use this variable here
echo $this->myVar;
}
}
}
Whenever I try using $this I get this error: 'Using $this when not in object context in...'
You should use $this->myVar
See the PHP Documentation - The Basics
<?php
class SimpleClass
{
// property declaration
public $var = 'a default value';
// method declaration
public function displayVar() {
echo $this->var;
}
}
?>
The pseudo-variable $this is available when a method is called from
within an object context. $this is a reference to the calling object
(usually the object to which the method belongs
Update:
In your new code sample, myInnerFunction is a nested function and is not accessible until the myFunction method is called. Once the myFunction method is called, the myInnerFunction becomes part of the global scope.
Maybe this is what you are looking for:
class myClass{
public $myVar;
public function myFunction() {
}
function myInnerFunction() {
//how do I use this variable here
echo $this->myVar;
}
}
Inner functions like myInnerFunction are always global in scope, even if they are defined inside of a member function in a class. See this question for another similar example
So, to PHP, the following are (almost) equivalent:
class myClass{
public $myVar;
public function myFunction() {
function myInnerFunction() {
//how do I use this variable here
echo $this->myVar;
}
}
}
And
class myClass{
public $myVar;
public function myFunction() {
}
}
function myInnerFunction() {
//how do I use this variable here
echo $this->myVar;
}
Hopefully the second example illustrates why $this is not even in scope for myInnerFunction. The solution is simply to pass the variable as a parameter to the function.
Pass it as an argument to the inner function.
You can use ReflectionProperty:
$prop = new ReflectionProperty("SimpleClass", 'var');
Full example:
class myClass{
public $myVar;
public function myFunction() {
function myInnerFunction() {
//how do I use this variable here
$prop = new ReflectionProperty("SimpleClass", 'myVar');
}
}
}
The solution above is good when you need each instance to have an own value. If you need all instances to have a same you can use static:
class myClass
{
public static $myVar = "this is my var's value";
public function myClass() {
echo self::$myVar;
}
}
new myClass();
see here