PHP pass variable outside of function without global variables - php

Let's say I have a function in php like this:
<?php function hello() {
$x = 2;
}
and I want to use that variable outside of this function without using global, since I've heard it's a bad idea because of it's security issues. (right?).
Anyway, what is the best way to get this value out? I would be able to do this in java by using "this". But not sure how that works in PHP. Thanks.
Update:
This is the code I needed help with:
<?php
require('includes/connect.php');
function connectHouseObjects() {
global $mysqli;
/* Register a prepared statement */
if ($stmt = $mysqli->prepare('SELECT x FROM house_room1 WHERE user_id = ?')) {
/* Bind parametres */
$stmt->bind_param('i', $user_id);
/* Insert the parameter values */
$user_id = 1;
/* Execute the query */
$stmt->execute();
/* Bind resultatet */
$stmt->bind_result($x);
while ($stmt->fetch()) {
//looping through the x's and y's
}
/* Close statement */
$stmt->close();
return $x;
} else {
/* Something went wrong */
echo 'Something went terrible wrong' . $mysqli->error;
}
}
?>

John Conde is right but to show you the code it would be
<?php
function hello() {
$x = 2;
return $x;
}
$var = hello();
echo $var;
?>

You can simply return your data:
function hello() {
$x = 2;
return $x;
}
and use its result wherever you want;
$x=hello();

Take this for example:
<?php
function hello(){
$x=2;
//this is where you get it out
return $x;
}
//here we are outside the function
$x = hello();
//$x now equals 2;
?>
Returning the variable from the function allows you to call the function and assign it outside.
Going more object oriented:
<?php
class Talk
{
protected $message;
public function setMessage($message){
//this will set your class variable to what ever is in $message
$this->message = $message;
}
public function getMessage()
{
//This will give you what ever your current message is
return $this->message;
}
}
//Then to use this you could do
$talk = new Talk();
//That sets up $talk to be an instance of the talk class
$talk->setMessage('Hello');
//This will then sets the message in talk to hello then to retrieve it just do
$message = $talk->getMessage();
//Now outside the class we have a variable $message that contains 'Hello'

You may also create a class, just like in Java, and use a class variable that can be accessed from other functions in that class.

You can simply return the value outside the function:
<?php
function hello() {
$x = 2;
return $x;
}
$x = hello();
If you want to return more than one value, you can use the list() function, while returning values as an array:
<?php
function hello() {
$x = 2;
$y = 3;
return array($x, $y);
}
list($x, $y) = hello();
You can find more information about the list() in the PHP manual

Related

PHP OOP by simply adding two numbers

<?php
class SimpleClass{
var $number1;
var $number2;
public function input_two_no($num1,$num2){
$this->number1=$num1;
$this->number2=$num2;
}
public function the_sum(){
$total = $number1+$number2;
return $total;
}
public function output_the_sum(){
echo $total;
}
$numbers = new SimpleClass;
$numbers->input_two_no(10,5);
$numbers->the_sum();
$numbers->output_the_sum();
}
?>
Please point out where i am going wrong in this.I am not getting the output yet.
There are several things you're doing wrong, such as:
Take this code block $numbers = new SimpleClass; ... $numbers->output_the_sum(); outside of the class.
See this statement inside the_sum() method,
$total = $number1+$number2;
You didn't declare any local variables named $number1 and $number2 inside the_sum() method. Instead, you should make use of the instance variables here.
See this statement in output_the_sum() method,
echo $total;
You didn't declare any local variable named $total inside output_the_sum() method. Instead, create an instance variable named $total and store the sum value in this instance variable. Later, you can display the total sum value using echo $this->total;.
So your code should be like this:
class SimpleClass{
var $number1;
var $number2;
var $total;
public function input_two_no($num1,$num2){
$this->number1=$num1;
$this->number2=$num2;
}
public function the_sum(){
$this->total = $this->number1+$this->number2;
}
public function output_the_sum(){
echo $this->total;
}
}
$numbers = new SimpleClass;
$numbers->input_two_no(10,5);
$numbers->the_sum();
$numbers->output_the_sum();
First off, you don't need the 2 Methods. input_two_no($num1,$num2) and output_the_sum(). You may, however, create a basic constructor method. Secondly, to access member-variables (Properties), you need to use php object-access notation (->). your class should have been as shown below. the sum method itself returns the sum of the 2 numbers passed as arguments.
class SimpleClass{
var $number1;
var $number2;
public function __construct($num1=null, $num2=null){
$this->number1 = $num1;
$this->number2 = $num2;
}
public function the_sum($number1=null, $number2=null){
if(!is_null($number1) && !is_null($number2)){
return null;
}
if( (!is_int($number1) || !is_float($number1) || !is_double($number1)) &&
(!is_int($number2) || !is_float($number2) || !is_double($number2))
){
return 'Numeric inputs only...';
}
$this->number1 = $number1;
$this->number2 = $number2;
return $this->number1 + $this->number2;
}
}
$numbers = new SimpleClass;
$output = $numbers->the_sum(10,5);
echo $output; //<== YIELDS 15

Array reference in a class error in php

I have this class which populates and prints an array
<?php
class testArray
{
private $myArr;
public function __construct() {
$myArr = array();
}
public static function PopulateArr() {
$testA = new testArray();
$testA->populateProtectedArr();
return $testA;
}
protected function populateProtectedArr()
{
$this->myArr[0] = 'red';
$this->myArr[1] = 'green';
$this->myArr[2] = 'yellow';
print_r ($this->myArr);
}
public function printArr() {
echo "<br> 2nd Array";
print_r ($this->myArr);
}
}
?>
I instantiate this class from another file and try to print the array in different function.
<?php
require_once "testClass.php";
$u = new testArray();
$u->PopulateArr();
$u->printArr();
?>
I am not able to print the array in the printArr() function. I want to get reference to the array that I had set the values in .
You just missed one thing, you have to assign result of $u->PopulateArr(); to $u again, otherwise you will not get the object you created from that method call, so:
$u = new testArray();
$u = $u->PopulateArr(); // this will work
$u->printArr();
This also can be done like this:
$u = testArray::PopulateArr();
$u->printArr();
It seems that your $u object never populates the private array.
Instead you create a new object $testA and populate its array.
This might help you understanding the way
class testArray
{
private $myArr;
public function __construct() {
$this->myArr = array();
}
public static function PopulateArr() {
$testA = new testArray();
$testA->populateProtectedArr();
return $testA;
}
protected function populateProtectedArr()
{
$this->myArr[0] = 'red';
$this->myArr[1] = 'green';
$this->myArr[2] = 'yellow';
return $this->myArr;
}
public function printArr() {
echo "<br> 2nd Array";
return $this->PopulateArr();
}
}
another.php
require_once "testClass.php";
$u = new testArray();
print_r($u->PopulateArr());
print_r($u->printArr());
Here we are accessing the values of protected function PopulateArr instead of printing within function I just replaced it with return and print it over another file and within printArr function just call the PopulateArr function and that's it

Passing variable between functions - php

Below is an edited version of my actual code:
<?php
include ('login_info.php');
class modernCMS {
var $host;
var $username;
var $password;
var $db;
var $url;
function connect(){
$con = mysql_connect($this->host, $this->username, $this->password);
mysql_select_db($this->db, $con) or die(mysql_error());
mysql_set_charset('utf8');
}
function get_coordinates(){
$sql ="select lat, lng from postcodes LIMIT 1;";
$res = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_assoc($res)){
$lat = $row['lat'];
$lng = $row['lng'];
}
}
function get_name(){
$sql ="select name from places WHERE lat=$lat AND lng=$lng LIMIT 1;";
$res = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_assoc($res)){
$name = $row['name'];
echo $name;
}
}
?>
Then within a separate document i have an include for the file above. I call the function get name using the following:
<?=$obj->get_name()?>
get_name actually contains a calculation for calculating the distance between two points however because its a lengthy calculation i have left it out of the example above.
Its important that i can just use $obj->get_name() to get the output for $lat and $lng
Functions operate within function scope, so the variables that you've set in get_coordinates() are local variables. To create global variables, you can use the global keyword:
<?php
function get_coordinates()
{
global $lat, $lng;
$lat = 25;
$lng = 5;
}
function display_coordinates()
{
global $lat, $lng;
echo $lat;
echo $lng;
}
get_coordinates();
display_coordinates();
Or $GLOBALS array:
<?php
function get_coordinates()
{
$GLOBALS['lat'] = 25;
$GLOBALS['lng'] = 5;
}
function display_coordinates()
{
echo $GLOBALS['lat'];
echo $GLOBALS['lng'];
}
get_coordinates();
display_coordinates();
However, this may not be the best way to set/access these variables because any function can change their state at any time, and you must call one function to set them before calling the other to display them. If you can describe your specific goal, you might be able to get better advice.
One better way to accomplish this is to use a class, and pass the object where you need it (this simple example does not demonstrate proper encapsulation, but is a good starting point):
<?php
class Coordinates {
public $lat;
public $lng;
public function __construct($lat, $lng) {
$this->lat = $lat;
$this->lng = $lng;
}
public function display_coordinates() {
echo $this->lat . "\n";
echo $this->lng . "\n";
}
}
function get_coordinates() {
return new Coordinates(25, 5);
}
$coords = get_coordinates();
$coords->display_coordinates();
function output_coordinates($coordinates) {
$coordinates->display_coordinates();
}
output_coordinates($coords);
Another way that is commonly used in PHP is to pass things in associative arrays (arrays with strings for indexes). I don't prefer this usually, because the array does not declare what it intends to hold, but it is an option:
<?php
function get_coordinates() {
return array('lat' => 25, 'lng' => 5);
}
function output_coordinates($coordinates) {
echo $coordinates['lat'] . '\n';
echo $coordinates['lng'] . '\n';
}
$coords = get_coordinates();
output_coordinates($coords);
You're running into a scoping issue. The variables are only available to the function that declared them. To make them available, you can either pass the variables to the function explicitly (you need to make sure you always call get_coordinates() before display_coordinates() though, otherwise you'll have undefined values), or using global variables (bad idea).
The best method is probably to make a class for it (although it depends on how you intend to use it). Your variables will always be in scope, and you won't run the risk of trying to run the display_coordinates() function before you've initialized the variables.
class Coordinate
{
// These are the variables where the coords will be stored.
// They are available to everything within the {}'s after
// "class Coordinate" and can be accessed with
// $this->_<varname>.
protected $_lat;
protected $_long;
// This is a special function automatically called when
// you call "new Coordinate"
public function __construct($lat, $long)
{
// Here, whatever was passed into "new Coordinate" is
// now stored in our variables above.
$this->_lat = $lat;
$this->_long = $long;
}
// This takes the values are stored in our variables,
// and simply displays them.
public function display()
{
echo $this->_lat;
echo $this->_long;
}
}
// This creates a new Coordinate "object". 25 and 5 have been stored inside.
$coordinate = new Coordinate(25, 5); // 25 and 5 are now stored in $coordinate.
$coordinate->display(); // Since $coordinate already "knows" about 25 and 5
// it can display them.
// It's important to note, that each time you run "new Coordinate",
// you're creating an new "object" that isn't linked to the other objects.
$coord2 = new Coordinate(99, 1);
$coord2->display(); // This will print 99 and 1, not 25 and 5.
// $coordinate is still around though, and still knows about 25 and 5.
$coordinate->display(); // Will still print 25 and 5.
You should read up on Variable Scope and Classes and Objects to understand more about this.
To put this together with your original code, you would do something like this,
function get_coordinates()
{
return new Coordinate(25, 5);
}
function display_coordinates($coord)
{
$coord->display();
}
$c = get_coordinates();
display_coordinates($c);
// or just "display_coordinates(get_coordinates());"
Edit after question updated
There are a few bad practices in your code, but here's some quick steps to get what you want.
// Copy the Coordinate class from my answer above, but add two new
// lines before the final "}"
public function getLatitude() { return $this->_lat; }
public function getLongitude() { return $this->_long; }
// Put the Coordinate class definition before this line
class modernCMS {
/////
// In your code, after this line near the top
var $url;
// Add this
var $coord;
/////
// In your get_coordinates(), change this...
$lat = $row['lat'];
$lng = $row['lng'];
// To this...
$this->coord = new Coordinate($lat, $lng);
/////
// In your get_name(), add two lines to the start of your function.
function get_name(){
$lat = $this->coord->getLatitude();
$lng = $this->coord->getLongitude();
Unrelated to your question, but you should also read about "SQL Injection" as query in get_name() is vulnerable. Not a big deal here, since the data comes from your other query anyway, but still good practice not to use parameters directly in a query string.
What about Session?
https://www.php.net/manual/en/reserved.variables.session.php
Creating New Session
session_start();
/*session is started if you don't write this line can't use $_Session global variable*/
$_SESSION["newsession"]=$value;
Getting Session
session_start();
/*session is started if you don't write this line can't use $_Session global variable*/
$_SESSION["newsession"]=$value;
/*session created*/
echo $_SESSION["newsession"];
/*session was getting*/
Updating Session
session_start();
/*session is started if you don't write this line can't use $_Session global variable*/
$_SESSION["newsession"]=$value;
/*it is my new session*/
$_SESSION["newsession"]=$updatedvalue;
/*session updated*/
Deleting Session
session_start();
/*session is started if you don't write this line can't use $_Session global variable*/
$_SESSION["newsession"]=$value;
unset($_SESSION["newsession"]);
/*session deleted. if you try using this you've got an error*/
One way of doing it:
function get_coordinates(&$lat, &$lng)
{
$lat = 25;
$lng = 5;
}
function display_coordinates($lat, $lng)
{
echo $lat;
echo $lng;
}
$lat = 0;
$lng = 0;
// assign values to variables
get_coordinates( $lat, $lng );
// use function to display them...
display_coordinates ($lat, $lng);
Create a Coordinate.class.php file:
<?php
class Coordinate {
var $latitude;
var $longitude;
public function getLatitude() {
return $this->latitude;
}
protected function setLatitude($latitude) {
$this->latitude = floatval($latitude);
}
public function getLongitude() {
return $this->longitude;
}
protected function setLongitude($longitude) {
$this->longitude = floatval($longitude);
}
public function __construct() {
// Overload
if (func_num_args() == 2) {
$this->setLatitude(func_get_arg(0));
$this->setLongitude(func_get_arg(1));
}
// Default
else {
$this->setLatitude(0);
$this->setLongitude(0);
}
}
public function displayCoordinate() {
printf("Latitude: %.2f, Longitude: %.2f\n",
$this->getLatitude(),
$this->getLongitude());
}
}
function main() {
$c = new Coordinate (25, 5);
$c->displayCoordinate();
}
main();
?>
Change of another post.. I think the better way:
function get_coordinates()
{
return array(
"lat" => 25,
"lng" => 5
);
}
function display_coordinates($latLongArray)
{
echo $latLongArray['lat'];
echo $latLongArray['lng'];
}
// assign values to variables
$latLongArray = get_coordinates();
// use function to display them...
display_coordinates ($latLongArray);

Anonymous functions in a class

is there a better way to call an anonymous function inside a class? Here is a simple example that clearifies what I mean.
class foo
{
private $call_back_1 = null;
private $call_back_2 = null;
function __construct($func1, $func2)
{
$this->call_back_1 = func1;
$this->call_back_2 = func2;
}
function provokeCallBacks()
{
//this does not work, and gives an error
$this->call_back_1();
//I would like to avoid this
$method = $this->call_back_2;
$method();
}
}
$call1 = function(){ echo "inside call 1"};
$call2 = function(){ echo "inside call 2"};
$test = new foo(call1, call2);
$test->provokeCallBacks();
* Update 1: Please ignore any syntax error as I have written this on the fly for demo puposes. *
Inside foo:provokeCallBacks, I am trying to call the anonymous functions how ever the first way does not works and gives an error. The second one works but it's a bit stupid that I have to use a temp variable called "$method" to make the call.
I want to know if there exists a better way to call the anonymous function.
call_user_func($this->call_back_1);
No, it's not possible to call an anonymous function via $this.
Another options is;
call_user_func($this->call_back_1);
Being PHP loosely typed, it can't do like {$this -> callback}(); you have to store it in a temp variable or to use call_user_func() either.
EDIT - consider something like this:
class Lambdas
{
protected $double;
protected $triple;
public function __construct($double, $triple)
{
$this -> double = $double;
$this -> triple = $triple;
}
public function __call($name, $arguments)
{
if( is_callable($this -> {$name}) ){
return call_user_func_array($this -> {$name}, $arguments);
}
}
}
$lambdas = new Lambdas(
function($a){ return $a * 2;},
function($a){ return $a * 3;}
);
echo $lambdas -> double(2); // prints 4
echo $lambdas -> triple(2); // prints 6
Dirty and dangerous, but you might succeed using eval..
class foo
{
private $call_back_1 = null;
private $call_back_2 = null;
function __construct($func1, $func2)
{
$this->call_back_1 = func1;
$this->call_back_2 = func2;
}
function provokeCallBacks()
{
eval($this->call_back_1);
eval($this->call_back_2);
}
}
call1 = 'echo "inside call 1"';
call2 = 'echo "inside call 2"';
$test = foo(call1, call2);
$test->provokeCallBacks();
I know your question has been answered but you can try changing your approch ..
class Foo {
private $calls = array();
function __set($key, $value) {
$this->calls[$key] = $value;
}
function __call($name, $arg) {
if (array_key_exists($name, $this->calls)) {
$this->calls[$name]();
}
}
function __all() {
foreach ( $this->calls as $call ) {
$call();
}
}
}
$test = new Foo();
$test->A = function () {
echo "inside call 1";
};
$test->B = function () {
echo "inside call 2";
};
$test->A(); // inside call 1
$test->B(); // inside call 2
$test->__all(); // inside call 1 & inside call 2

Initialize static array for use it in other static variable of other class

class Assignation {
private $VVal_1 = 1;
private $VNam_1 = "One";
//....Multiple Items
private $VVal_2000 = 2000; //For Example
private $VNam_2000 = "Two Thousands"; //For Example
private static $Hash = array(); //How to initialize???
private static function Assigning(){
//This function for to assign the array elements (initialize)
global $Hash;
$this->Hash = array(); //to empty Hash variable and not add more data than it should.
$this->Hash[$this->VVal_1] = $this->VNam_1;
//....Multiple Items
$this->Hash[$this->VVal_2000] = $this->VNam_2000;
}
public static function GetVal($Nam) {
$this->Assigning(); //or use self::Assigning(); //I want to avoid this call
if (array_search($Nam, $this->Hash))
return array_search($Nam, $this->Hash);
return -1;//error
}
public static function GetNam($Val) {
$this->Assigning(); //or use self::Assigning(); //I want to avoid this call
if (array_key_exists($Val, $this->Hash))
return $this->Hash[$Val];
return "Error";
}
}
Class Testing {
static $OtherVal = Assignation::GetVal("BLABLA"); //for example
static $OtherNam = Assignation::GetNam(20); //for example
//Other functions...
}
Hi, you can see my script or code php...
I need to initialize the Hash array, this have static word because I need to use it in other static function. And this "other function" need to use it for other static variable...
I need to know how to implement it the right way..
Thanks chep.-.
<?php
echo "pre-Class Assignation<br/>";
class Assignation {
private $VVal_1 = 1;
private $VNam_1 = "One";
private $VVal_2K = 2000;
private $VNam_2K = "Two Thousands";
private static $Hash = array();
private static function Assigning(){
if(!empty(self::$Hash)) return;
self::$Hash[$this->VVal_1] = $this->VNam_1;
self::$Hash[$this->VVal_2K] = $this->VNam_2K;
}
public static function GetVal($Nam) {
self::Assigning();
if (array_search($Nam, self::$Hash)) return array_search($Nam, self::$Hash);
return -1;//error
}
public static function GetNam($Val) {
self::Assigning();
if (array_key_exists($Val, self::$Hash)) return self::$Hash[$Val];
return "Error";
}
}
echo "post-Class Testing<br/>";
echo Assignation::GetVal("BLABLA");
echo "post-Class Mid<br/>";
echo Assignation::GetNam(20);
echo "post-Class Sample<br/>";
//Testing::MyPrint();
?>
This code is not running, somebody help me testing the code...
result:
pre-Class Assignation
post-Class Assignation
post-Class Testing
that mean:
" echo Assignation::GetVal("BLABLA");"
have error...
In Assigning(), try using self::$Hash rather than $this->Hash and remove the global $Hash. Same applies for calling Assigning(): self::Assigning() as your comments suggest.
$this references the current object, so you must use self:: for all static functions and member data when inside the class.
Also, if this is your real code and not just a sample, you may want to check whether you have already done initialization, otherwise you will be doing it for every call to GetVal() and GetNam(). You could do this by adding something like if(!empty(self::$Hash)) return at the beginning of Assigning()
EDIT
private static function Assigning() {
if(!empty(self::$Hash)) return; // already populated
self::$Hash = array();
self::$Hash[$this->VVal_1] = $this->VNam_1;
//....Multiple Items
self::$Hash[$this->VVal_2K] = $this->VNam_2K;
}

Categories