PHP use class function on sub-functions - php

i have test class with one function , after including that i can use this class function with included pages but i cant use this function on included page's functions, for example:
testClass.php:
class test
{
public function alert_test( $message )
{
return $message;
}
}
including class:
in this using class i dont have problem
text.php:
<?php
include 'testClass.php';
$t= new test;
echo alert_test('HELLO WORLD');
?>
but i cant use alert_test function with this method:
<?php
include 'testClass.php';
$t= new test;
function test1 ( $message )
{
echo alert_test('HELLO WORLD');
/*
OR
echo $t->alert_test('HELLO WORLD');
*/
}
?>
i want to use test class in sub-functions

What about echo $t->alert_test('HELLO WORLD');? You have to 'tell' PHP where he has to find that function, in this case in $t which is an instance of the test class.
<?php
include 'testClass.php';
function test1 ( $message )
{
$t = new test;
echo $t->alert_test('HELLO WORLD');
}
?>

You should pass the instance ($t) to your function, i.e:
<?php
class test
{
public function alert_test( $message )
{
return $message;
}
}
$t = new test;
function test1 ( $message, $t )
{
echo $t->alert_test('HELLO WORLD');
}
As an alternative (better IMHO) you could declare your function as static, so that you don't even need to instantiate the test class, i.e:
class Message {
static function alert($message) {
echo $message;
}
}
function test_alert($msg) {
Message::alert($msg);
}
test_alert('hello world');

You should "have problem" even in your first example, because alert_test() is an instance function of your test class.
You have to invoke instance methods as:
$instance -> method( $params );
So:
$t -> alert_test();
But local functions [as your test1] should not rely on global objects: pass them as a function argument, if you need.

You can use closures:
$t = new test;
function test1($message) use ($t) {
$t->test_alert($message);
}

Related

Php Include properties within class

I'm having an issue calling a variable thats included in a class. What am I missing here? Thank you in advance for the support. Very much appreciated.
//index2.php
$var2 = 'var2';
//index.php
class something {
__construct() {
include('index2.php');
}
}
$run_it = new something();
echo $run_it->var2; //how do I call var2?
You could do this. Kind of a strange way to do things but here goes:
index.php
<?php
class something{
function __construct() {
include('index2.php');
}
}
//s1
$s1 = new something();
$s1->var2 = 'var2 changed';
//s2
$s2 = new something();
//print em out
print_r($s1);
print_r($s2);
index2.php
<?php
$this->var2 = 'var2'; //$this pseudo-variable works because we're including index2.php within the scope of our class instance
?>
Output
$ php a.php
something Object
(
[var2] => var2 changed
)
something Object
(
[var2] => var2
)
You cannot extend property's of a class with including files. The class is defined as it is written. You have the following ways to add code to a class dynamically.
Extend a class.
Use traits (copy pasting functions into a class)
Use magic methods (__call, __get, __set)
This example will print variables defined in the global scope (like your example) as you wanted it to do.
However, this is not the way it should be used and I suggest finding a different method of writing your class.
include 'somefile.php'; // <?php $var3 = 'testing' ?>
class foo{
public $var2 = 'var2'; # should be declared within the class.
public function __get($name){
// property 'var3' is not defined in the class so this method is magically called instead.
if(isset($GLOBALS[$name])){
return $GLOBALS[$name]; // Here we return the value $var3 defined in the global scope.
} else {
trigger_error("Call to undefined variable '$name'");
}
}
public function __construct(){ # Missed function statement.
echo 'hello';
}
}
$c = new foo();
echo $c->var3; // testing
If your index2.php contains this:
$var2 = 'var2';
Then you can include that file to get access to $var2. You can then pass that variable to your something constructor as an argument:
//index.php
class something {
public $var2;
public function __construct($arg) {
$this->var2 = $arg;
}
}
include 'index2.php';
$run_it = new something($var2);
echo $run_it->var2; // echos 'var2'
It's obvious there are other ways to do something like what you're attempting to do (there is usually more than one way to do most things), but really the most sensible way to get external data into your object is to pass it via constructor arguments.
If you don't do this, the class will forever depend on some other file existing in the correct location relative to the class or calling file, with all of the correct variables set in it. If that file is altered or moved, objects of that class may not function properly if they can even be instantiated at all.
I agree with Xorifelse, you can do it with traits. example.
fields.php
trait Aa {
public $fields = [
"name"=>"string->5",
"number"=>"integer->3",
];
}
traits.php
include('fields.php');
class ABC {
use Aa;
public function __set($field,$value)
{
if(array_key_exists($field,$this->fields))
{
$this->fields[$field] = $value;
}
else
{
$this->fields[$field] = null;
}
}
public function __get($field)
{
if(array_key_exists($field,$this->fields))
{
return $this->fields[$field];
}
else
{
return null;
}
}
}
$a = new ABC();
$a->number = 111;
var_dump($a->fields);
array(2) {
["name"]=>
string(9) "string->5"
["number"]=>
int(111)
}
var_dump($a->number);
int(111)
You can take advantage of get_defined_vars. Assuming your variables are in a file (e.g. filevars.php):
filevars.php
<?php
$name = 'myName';
$address = 'myAddress';
$country = 'myCountry';
$phones = array('123456789','987654321');
?>
You can add a method to your class (getVars) and define a property (vars) that wraps all variables existing in filevars.php:
class-test.php
<?php
class Test
{
public $vars;
function getVars()
{
include ('filevars.php');
$this->vars = get_defined_vars();
}
}
?>
Usage
<?php
include ('class-test.php');
$myClass = new Test();
$myClass->getVars();
print_r($myClass->vars);
?>
Output:
Array
{
[name] => myName
[address] => myAddress
[country] => myCountry
[phones] => Array
{
[0] => 123456789
[1] => 987654321
}
}
You can also refer any individual included variable, e.g.:
echo $myClass->vars['country']; // myCountry

Get namespace of call context

I have a very simple question, but the answer might be rather complicated.
"How can I get the namespace of the block where a function call was made?"
So, when I do:
1. <?php
2. namespace TestTest;
3.
4. $myobj->doMethod();
How can $myobj->doMethod() know that the namespace on line 4. is TestTest?
This is only possible if the method is not called from the global scope. That's because there's no real way to backtrace it (please someone correct me here if that's not the case!). Simplest solution is to put your call in a function. It's likely you'll be using a method anyway if you're doing this sort of thing. If that's the case then you can use a combination of the debug_backtrace function and the reflection class:
file1.php:
<?php
namespace myns;
require 'file2.php';
function example($class) {
echo $class->nstest();
}
$class = new \myotherns\someclass();
echo example($class);
file2.php:
<?php
namespace myotherns;
class someclass {
function nstest() {
$backtrace = debug_backtrace();
$caller = end($backtrace);
$reflection = new \ReflectionFunction($caller['function']);
return $reflection->getNamespaceName();
}
}
Or all in one file:
<?php
namespace myns {
$someclass = new \myotherns\someclass();
echo example($someclass);
function example($class) {
echo $class->nstest();
}
}
namespace myotherns {
class someclass {
function nstest() {
$backtrace = debug_backtrace();
$caller = end($backtrace);
$reflection = new \ReflectionFunction($caller['function']);
return $reflection->getNamespaceName();
}
}
}
Here's an online demo
You'll need to tweak it depending on how you end up calling your method, but it should be simple enough.

Get name of a class from where the function was called in PHP

I have two separate classes where one of them is a logging class. I would like to be able to tell which class is calling the log class functions without passing any parameters.
<?php
class Log {
public function general($message) {
// Tell which class/function is calling this function here
$class = get_called_class();
echo 'Your message was: "'.$message.'" from class: "'.$class.'"';
}
}
class foo {
public function log_something() {
$Log = new Log();
$Log->general('Hello, world!');
}
}
$foo = new Foo();
$foo->log_something();
?>
The output I would like is: Your message was "Hello, world!" from class "foo"
However, the message I'm getting is:
Your message was "Hello, world!" from class "Log"
Am I missing something, or doing something wrong?
You just creating the Log object inside of Foo, therefore your get_called_class() call will always result in Log. You need to make Foo inherit Log if you want that kind of behavior. For example:
<?php
class Log {
public function msg($message) {
// Tell which class/function is calling this function here
$class = get_called_class();
echo 'Your message was: "'.$message.'" from class: "'.$class.'"';
}
}
class Foo extends Log {
public function doSomething() {
$this->msg( 'Hello World!' );
}
}
$foo = new Foo();
$foo->doSomething();
Outputs:
Your message was: "Hello World!" from class: "Foo"
I was able to figure out the answer to my problem by using debug_backtrace()
<?php
class Log {
private function get_call_class() {
$backtrace = debug_backtrace();
$classes = array();
foreach ($backtrace as $item) {
if ($item['class'] != '' && $item['class'] != 'Log') $classes[] = $item['class'];
}
return $classes[0];
}
public function general($message) {
// Tell which class/function is calling this function here
$class = $this->get_call_class();
echo 'Your message was: "'.$message.'" from class: "'.$class.'"';
}
}
class foo {
public function log_something() {
$Log = new Log();
$Log->general('Hello, world!');
}
}
$foo = new Foo();
$foo->log_something();
?>
Explanation: The Log->get_call_class() function gets information from debug_backtrace() and loops through it to find the classes that don't have the name of 'Log' or blank names then returns the first result, which is the one I was looking for.

How do I get the function name inside a function in PHP?

Is it possible?
function test()
{
echo "function name is test";
}
The accurate way is to use the __FUNCTION__ predefined magic constant.
Example:
class Test {
function MethodA(){
echo __FUNCTION__;
}
}
Result: MethodA.
You can use the magic constants __METHOD__ (includes the class name) or __FUNCTION__ (just function name) depending on if it's a method or a function... =)
If you are using PHP 5 you can try this:
function a() {
$trace = debug_backtrace();
echo $trace[0]["function"];
}
<?php
class Test {
function MethodA(){
echo __FUNCTION__ ;
}
}
$test = new Test;
echo $test->MethodA();
?>
Result: "MethodA";

Run code on creation of a PHP class instance?

I want code to run whenever I create a new object. For example, see this:
<?php
class Test {
echo 'Hello, World!';
}
$test = new Test;
?>
I want it to echo "Hello, World!" whenever I create a new instance of this object, without calling a function afterward. Is this possible?
You should read about constructor
<?php
class MyClass {
public function __construct() {
echo "This code is executed when class in instanciated.";
}
}
?>
class Test {
function __construct(){
echo 'Hello, World!';
}
}
Or on PHP 4 use:
class Test {
function Test {
echo 'Hi';
}
}
Edit: This also works on PHP 5, so this is the best way to do it.

Categories