php: how to make a method inside a class run? - php

I started learning oop php and I don't understand how to make a method inside a class execute.
This is the code:
class GrabData {
public $tables=array();
public $columns=array();
public $argList;
function __construct(){
$this->argList=func_get_args();
$pattern;
var_dump($this->argList);
if(!empty($this->argList)){
foreach($this->argList as $value){
if(preg_match("/.+_data/",$value,$matches)){
if(!in_array($matches[0],$this->tables)){
array_push($this->tables,$matches[0]);
var_dump($this->tables);
}
$pattern="/". $matches[0] . "_" . "/";
array_push($this->columns,preg_replace($pattern,"",$value));
var_dump($this->columns);
}
}
}
}
public function gen_query(){
var_dump($this->argList);
echo "haha";
}
gen_query();
}
new GrabData("apt_data_aptname");
Now, the __construct function runs when I make a new GrabData object, but the gen_query function doesnt execute. How do I make it execute it ?

If you always want to have the gen_query function run when the class is initiated, you could link to it in the bottom of your constructor, like so:
function __construct() {
// Do your stuff here and then...
$this->gen_query();
}

First, you assign the object returned by the new operator to a variable - then use that variable to execute methods on your object:
class GrabData {
public $tables=array();
public $columns=array();
public $argList;
function __construct() {
$this->argList=func_get_args();
$pattern;
var_dump($this->argList);
if(!empty($this->argList)){
foreach($this->argList as $value){
if(preg_match("/.+_data/",$value,$matches)){
if(!in_array($matches[0],$this->tables)){
array_push($this->tables,$matches[0]);
var_dump($this->tables);
}
$pattern="/". $matches[0] . "_" . "/";
array_push($this->columns,preg_replace($pattern,"",$value));
var_dump($this->columns);
}
}
}
}
public function gen_query() {
var_dump($this->argList);
echo "haha";
}
}
$super_object = new GrabData("apt_data_aptname");
$super_object->gen_query();

A different way to run a class function without initiating the class is to use the double colon scope resolution operator, strangely called "Paamayim Nekudotayim".
GrabData::gen_query();
You can read up on it here.

Related

PHP If Statement in Class to set protected variable

I'm trying to set a class Variable dependent on an if statement in PHP that's available to all the functions in the class. Just setting the variable works fine, but as soon as I attempt to set from an IF statement everything is breaking.
Examples:
Works
class Default_Service_NewSugar {
protected $base_url = "http://url1";
function test() {
return $this->base_url;
}
}
Doesn't work
class Default_Service_NewSugar {
if($_SERVER['APPLICATION_ENV']=="development"){
protected $base_url = "http://url1";
} else {
protected $base_url = "https://url2";
}
function test() {
return $this->base_url;
}
}
Is this not possible in a class? If not is there an alternative way I should be approaching this?
The main problem is that you are putting procedural code inside a class. Referencing to the PHP.net documentation:
A class may contain its own constants, variables (called "properties"), and functions (called "methods").
php.net
I would recommend reading the PHP manual on how to work with OOP, and read many of the OOP tutorials available on the web.
As mentioned in other answers you should do the initializing work inside the class constructor.
class Default_Service_NewSugar
{
protected $base_url;
public function __construct()
{
$this->base_url = ($_SERVER['APPLICATION_ENV'] == "development")
? "http://url1"
: "https://url2";
}
function test()
{
return $this->base_url;
}
}
A more OOP like approach would be to set the URL inside a configuration file and pass the variable to the class when initiating the class.
class Default_Service_NewSugar
{
protected $base_url;
public function __construct($base_url)
{
$this->base_url = $base_url;
}
function test()
{
return $this->base_url;
}
}
//usage would then be:
$default_service = new Default_Service_NewSugar($url_from_configuration_file);
$default_service->test(); //outputs the given URL
You should write that conditional statement inside the constructor. And also, no need to specify the access specifier every time the variable is being initialized, you can specify once and in the initialization part just assign the value. And also optimize your code as well.
class Default_Service_NewSugar {
protected $base_url = "http://url";
function __construct() {
$this->base_url .= $_SERVER['APPLICATION_ENV']=="development" ? 1 : 2;
}
function test() {
return $this->base_url;
}
}
You have lots of typos and that's not the perfect way to work around variables within class
class Default_Service_NewSugar {
protected $base_url;
public function __construct() {
$this->base_url = ($_SERVER['APPLICATION_ENV'] == "development") ? "http://url1" : "http://url2";
}
public function test() {
return $this->base_url;
}
}
As already mentioned, you may initiate your variable inside constructor. Another approach to achieve your goal is to use property access function instead of direct object field access. In this way, you may add additional conditions easily and the code will look like this:
class Default_Service_NewSugar {
public function __construct() {
}
public function getBaseURL($env = null) {
$env = $env ? $_SERVER['APPLICATION_ENV'] : $env;
return ($env == "development") ? "http://url1" : "http://url2";
}
}
$obj = new Default_Service_NewSugar();
print $obj->getBaseURL();

Call static function from variable

I have the following setup:
class test {
public static function something() {
$somethingElseFunction = "somethingElse";
// How can I call the method with the name saved in variable?
}
public static function somethingElse($a) {
echo 'bla';
}
}
How can I call the function using the variable? (the function name is in variable).
Also I need to do a function_exists() for it.
Tried this:
if (function_exists(self::$somethingElseFunction ())) {
if (!call_user_func(self::$somethingElseFunction , $a)) {
}
}
Didn't work.
In PHP>=5.4 you can use just self:: de-reference:
self::$somethingElseFunction();
-but in earlier versions that will cause error (because it wasn't allowed to use dynamic static methods de-reference). So then you can always use such things as call_user_func_array() :
class test {
public static function something() {
$somethingElseFunction = "somethingElse";
call_user_func_array(array(__CLASS__, $somethingElseFunction), array("bla"));
}
public static function somethingElse($a) {
var_dump($a);
}
}
test::something();
-this will work for PHP>=5.0
About function_exists() call - it expects string as parameter, thus I recommend to use method_exists() - because that function is intended to do the stuff:
public static function something() {
$somethingElseFunction = "somethingElse";
if(method_exists(__CLASS__, $somethingElseFunction))
{
call_user_func_array(array(__CLASS__, $somethingElseFunction), array("bla"));
}
}
You should be able to use the following:
test::$somethingElseFunction();
Use this function:
$classname = 'somethingElse';
call_user_func('test::' . $classname, $params);

Referencing class function variables in php

I've been looking over the PHP variable scope reference page and I can't seem to find a clear answer. I'm working with this basic model where I want to call a class function and have all of its variables accessible outside the class. I want to avoid using the global declaration as well and do this in the most efficient way possible.
class my_class() {
function my_class_function() {
$my_class_function_variable = 'juice';
return $my_class_function_variable;
}
}
$class_instance = new my_class();
function display_juice() {
$class_instance::my_class_function();
$my_class_function_variable;
}
Is there a quick answer in what I'm missing? I'm not getting any output or errors.
EDIT
I'm getting a syntax error when I declare the following within the class but not within the function.
public $current_user = wp_get_current_user();
Parse error: syntax error, unexpected '(', expecting ',' or ';'
You can access all setted variables in class if they are public.
And you can access any of its function if its again public...
Here is example . I have default value 'mydefault'.
I use it, then I change it and again I use it..
class my_class {
public $variable = "mydefault";
public function change_variable($value) {
$this->variable = $value;
}
}
function display_juice() {
$class = new my_class;
echo $class->variable; // echo default value - 'mydefault'
$class->change_variable('newvalue');
echo $class->variable; // echo default value - 'newvalue'
}
display_juice();
Edit..
class my_class {
public $variable;
public function __construct() {
$this->variable = wp_get_current_user();
}
}
You need to make my_class_function() static, the you can call it with my_class::my_class_function()
http://php.net/manual/en/language.oop5.static.php
Also as suggested bellow, you need to return 'juice'.
return 'juice';
You currently don't return anything, you would have to do something like this:
class my_class() {
function my_class_function() {
$my_class_function_variable = 'juice';
return $my_class_function_variable;
}
}
function display_juice() {
$class_instance = new my_class(); //Needs to be inside the function
$my_class_function_variable = $class_instance->my_class_function();
echo $my_class_function_variable;
}
display_juice();
If you want to use a static function or variable you could do this, which eliminates the need for having to create an instance of my_class:
class my_class() {
static function my_class_function() {
return 'juice';
}
}
function display_juice() {
$my_class_function_variable = my_class::my_class_function();
echo $my_class_function_variable;
}
display_juice();
I would make the variable you're trying to access a public member
class my_class {
public $my_class_function_variable = 'juice';
public function my_class_function() {
}
}
$class_instance = new my_class();
function display_juice() {
echo my_class->$my_class_function_variable;
}
display_juice();

can I pass __construct parameters after a class has been instantiated into an object?

I have a similar code snippet like this
class Search
{
public function search($for, $regEx, $flag) //I would like this to be the constructor
{
// logic here
return $this;
}
}
Then I have another class that creates an object from it, later than tries to use the object.
class MyClass
{
public function start()
{
$this->search = new Search();
}
public function load()
{
$this->search($for, $regEx, $flag);
}
}
My question is, is it possible to create an object first THEN give it the parameters?
I know there are some way around this BUT I only ask because I want to use the object like this
$this->search($params);
// I have my methods chained, so I could use it in one line like
// $this->search($params)->hasResults();
if ($this->search->hasResults()) {
echo 'found stuff';
} else {
echo 'didn't find anything';
}
The way I have it set up right now, I would need to use it like this
$this->search->search($params);
if ($this->search->hasResults()) {
echo 'found stuff';
} else {
echo 'didn't find anything';
}
I have a method called search() that does the logic, and I don't want to be redundant in my naming nor do I want to change the name of the method.
I know another way to keep the visual appeal sane I could pass a variable like so
$search = $this->search->search($params);
then
$search->hasResults();
At the same time I am trying to introduce myself to new OOP concepts and learn from them. Would this require passing things by reference? or setting up some type of magic method?
While the previous anwsers show that you can, I wouldn't use it, because it breaks the concept of encapsulation. A proper way to achieve what you want is the following
class Search
{
public function __constructor($for='', $regEx='', $flag='')
{
$this->Setup($for, $regEx, $flag);
}
public function Setup($for, $regEx, $flag)
{
//assign params
//clear last result search
//chain
return $this;
}
public function search()
{
// logic here
return $this;
}
}
In this way, you can reuse the object and have the params in the constructor, without breaking encapsulation.
Yes it is possible
See the below example
<?php
class a{
public $a = 5;
public function __construct($var){
$this->a = $var;
}
}
$delta = new a(10);
echo $delta->a."\n";
$delta->__construct(15);
echo $delta->a."\n";
Output will be:
10 15
Yep, you can.
class Example {
public $any;
function __counstruct($parameters,$some_text) {
$this->any=$some_text;
return $this->any;
}
}
You can call constructor:
$obj = new Example (true,'hello');
echo $obj->any;
$obj->__construct(true,'bye-bye');
echo $obj->any;
I was able to create the visual coding I wanted by using the __call() magic method like this
public function __call($name, $params)
{
$call = ucfirst($name);
$this->$name = new $call($params);
}
from there I could use this
$this->test->search($params);
$this->test->search->hasResults();
I of course now set the search() method to the class constructor

How to access to object methods when you pass an object as a parameter in PHP?

How can I call a method of an object passed as a parameter in PHP?
This is the first class defined in thefirstclass.php
class TheFirstClass {
private $_city='Madrid';
public function city() {
return $_city
}
}
This is the second class defined in thesecondclass.php
class TheSecondClass {
public function myMethod($firstClassObject) {
echo "City: " . $firstClassObject->city(); // <- Why This method doesn´t work?
}
}
And finally, this is
include_once "class/thefirstclass.php";
include_once "class/thesecondclass.php";
$firstClassObject = new TheFirstClass();
$secondClassObject = new TheSecondClass();
$secondClassObject->myMethod($firstClassObject);
The problem doesn't lie in the call to TheFirstClass::city within TheSecondClass::myMethod, but rather that TheFirstClass::city returns a local variable ($_city) rather than an instance variable ($this->_city). Unlike in languages such as C++, in PHP instance variables must always be accessed through an object, even in methods.
This is the working code:
class TheFirstClass {
private $_city = "a";
public function city() {
return $this->_city;
}
}
class TheSecondClass {
public function myMethod($firstClassObject) {
echo "City: " . $firstClassObject->city(); // <- Why This method doesn´t work?
}
}
$test = new TheFirstClass();
$test2 = new TheSecondClass();
$test2->myMethod($test);

Categories