Passing variable between functions - php - 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);

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

PHP pass variable outside of function without global variables

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

PHP function inside a class function include

I am working with lemonade-php. My code is at https://github.com/sofadesign/limonade.
The issue I am having is when I try to run
class syscore {
public function hello(){
set('post_url', params(0));
include("./templates/{$this->temp}/fullwidth.tpl");
return render('fullwidth');
}
}
which then loads the fullwidth.tpl and runs function fullwidth
fullwidth.tpl
<?php
global $post;
function fullwidth($vars){
extract($vars);
$post = h($post_url);
}
print_r($this->post($post));
?>
it seems to pass the $post_url but I can not pass it again to the print_r($this->post($post));
However when I try to run print_r($this->post($post)) inside the fullwidth function it says it can not find the post() function
I have tried a number of things like below
function fullwidth($vars){
extract($vars);
$post = h($post_url);
print_r(post($post));
}
I tried re connecting to the syscore by
$redi = new syscore();
$redi->connection() <-- this works
$redi->post($post) <-- this does not
Here is my full class syscore
class syscore {
// connect
public function connect($siteDBUserName,$siteDBPass,$siteDBURL,$siteDBPort, $siteDB,$siteTemp){
for ($i=0; $i<1000; $i++) {
$m = new Mongo("mongodb://{$siteDBUserName}:{$siteDBPass}#{$siteDBURL}:{$siteDBPort}", array("persist" => "x", "db"=>$siteDB));
}
// select a database
$this->db = $m->$siteDB;
$this->temp = $siteTemp;
}
public function hello(){
set('post_url', params(0));
include("./templates/{$this->temp}/fullwidth.tpl");
return render('fullwidth');
}
public function menu($data)
{
$this->data = $data;
$collection = $this->db->redi_link;
// find everything in the collection
//print $PASSWORD;
$cursor = $collection->find(array("link_active"=> "1"));
if ($cursor->count() > 0)
{
$fetchmenu = array();
// iterate through the results
while( $cursor->hasNext() ) {
$fetchmenu[] = ($cursor->getNext());
}
return $fetchmenu;
}
else
{
var_dump($this->db->lastError());
}
}
public function post($data)
{
$this->data = $data;
$collection = $this->db->redi_posts;
// find everything in the collection
//print $PASSWORD;
$cursor = $collection->find(array("post_link"=> $data));
if ($cursor->count() > 0)
{
$posts = array();
// iterate through the results
while( $cursor->hasNext() ) {
$posts[] = ($cursor->getNext());
}
return $posts;
}
else
{
var_dump($this->db->lastError());
}
}
}
It looks like you are having some issues understanding the execution path that PHP is taking when trying to render your template. Let's take a more in-depth look, shall we?
// We're going to call "syscore::hello" which will include a template and try to render it
public function hello(){
set('post_url', params(0)); // set locals for template
include("./templates/{$this->temp}/fullwidth.tpl"); // include the template
return render('fullwidth'); // Call fullwidth(array('post_url' => 'http://example.com/path'))
}
The trick to solving this one is to understand how PHP include works. When you call include("./templates/{$this->temp}/fullwidth.tpl") some of your code is executing in the scope of the syscore object, namely:
global $post;
and
print_r($this->post($post));
fullwidth is created in the global scope at this point, but has not yet been called. When render calls fullwidth you're no longer in the syscore scope, which is why you cannot put $this->post($post) inside without triggering an error.
Ok, so how do we solve it? Glad you asked.
We could probably refactor syscore::post to be a static method, but that would then require syscore::db to be static, and always return the SAME mongodb instance (singleton pattern). You definitely do not want to be creating 1000 Mongo instances for each syscore instance.
We could just abuse the framework. A much poorer solution, but it will get the job done.
fullwidth.tpl
<?php
function fullwidth($vars){
$post_url = ''; // put the variables you expect into the symbol table
extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
$syscore_inst = new syscore;
$post = h($post_url);
print_r($syscore->post($post)); // I think a puppy just died.
}
Look the second way is a complete hack, and writing code like that will probably mean you won't get promoted. But it should work.
But let's say you wanted to get promoted, you would make good, shiny code.
// Note: Capitalized class name
class Syscore {
protected static $_db;
public static function db () {
if (! static::$_db) {
static::$_db = new Mongo(...);
}
return static::$_db;
}
// #FIXME rename to something more useful like "find_posts_with_link"
public static post($url) {
$collection = static::db()->redi_posts;
// find everything in the collection
$cursor = $collection->find(array("post_link"=> $url));
// Changed to a try-catch, since we shouldn't presume an empty find is
// an error.
try {
$posts = array();
// iterate through the results
while( $cursor->hasNext() ) {
$posts[] = ($cursor->getNext());
}
return $posts;
} catch (Exception $e) {
var_dump($this->db->lastError());
}
}
}
Then in your fullwidth function, we don't have to do any of that stupid nonsense of treating an instance method like it were a static method.
function fullwidth($vars){
$post_url = ''; // put the variables you expect into the symbol table
extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
$post = h($post_url);
print_r(Syscore::post($post)); // static method. \O/ Rainbows and unicorns.
}

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;
}

php session variable

my session variable seems to keep dropping its array values. What could I be doing wrong? Is it my object?
session_start() is initiated at the beginning,
if(isset($_SESSION['locations'])) {
unserialize($_SESSION['locations'])->listItems($_POST['companyLocation']);
echo "session exists";
}
else{
$_SESSION['locations'] = serialize(new Location());
unserialize($_SESSION['locations'])->listItems($_POST['companyLocation']);
echo "session does not exist";
}
class Location{
function listItems($location){
$array;
$array[] = $location;
//print_r($array);
// Re-index:
$array = array_values($array);
print_r($array);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "{$array[$i]}\n";
}
}
}
Do you have the following line at the beginning of your php script?
<?php
session_start();
...
Looking at your Location class, the listItems function looks horribly broken, what is is that you're trying to do?
A quick refactor of your Location class based on your comment:
class Location {
private $locations;
public static function instance($args = null) {
return empty($_SESSION['locations']) ?
new Location($args) : unserialize($_SESSION['locations']);
}
public function __construct($locations = null) {
$this->locations = empty($locations) ? array() : $locations;
}
public function addLocation($location) {
$this->locations[] = $location;
}
public function listItems() {
print_r($this->locations);
}
public function saveInstance() {
$_SESSION['locations'] = serialize($this);
}
}
Usage would be:
<?php
session_start();
$location = Location::instance();
if(!empty($_REQUEST['companyLocation']));
$location->addLocation($_REQUEST['companyLocation']);
$location->listItems();
...
$location->saveInstance();
?>
The first things that come to mind:
Are you remembering to use session_start() at the top of every page, before headers are sent? if not, then no session information is stored between pages.
$_SESSION['locations'] is being set to an object. You never serialized the object, which can cause issues trying to store it into a session. See http://www.php.net/manual/en/language.oop5.serialization.php for more information on object serialization, and storing them in the session object.

Categories