My homepage contains weather for three cities around the world as displayed in the image
In the home page I declare 3 variables storing the RSS URL for each city
$newYorkWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=USNY0996&u=f';
$londonWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=UKXX0085&u=c';
$parisWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=FRXX0076&u=c';
I pull identical tags out of the three URL's displayed above and use 3 identical functions apart apart from the variable passed into it.
Below shows the variable being passed into the function. Obviously other functions are used before $weather can be returned.
function new_york_current_weather($newYorkWeatherSource) {
// Get XML data from source
if (isset($newYorkWeatherSource)) {
$feed = file_get_contents($newYorkWeatherSource);
} else {
echo 'Feed not found. Check URL';
}
checkWeatherFeedExists($feed);
$xml = new SimpleXmlElement($feed);
$weather = get_dateTime($xml);
$weather = get_temperature_and_convert($xml);
$weather = get_conditions($xml);
$weather = get_icon($xml);
return $weather;
}
As I mentioned, I current repeat this function 3 times just replacing the $newYorkWeatherSource variable that is passed in the above example. Any ideas how I could reuse this function 3 times but yet pass in different URL to keep my homepage showing weather from the 3 cities? Ofcourse, it's easy to reuse the function if each city was represented on individual pages but the purpose is to keep them together for comparison.
Any ideas?
Thanks in advance.
As I mentioned, I current repeat this function 3 times just replacing the $newYorkWeatherSource variable that is passed in the above example. Any ideas how I could reuse this function 3 times but yet pass in different URL to keep my homepage showing weather from the 3 cities?
Maybe I'm entirely missing the point of your question, but are you asking how to rename the function and variables? Because, if so, it's just a matter of search and replace on the first few lines of the function...
function get_current_weather($rss_url) {
// Get XML data from source
if (isset($rss_url)) {
$feed = file_get_contents($rss_url);
} else {
echo 'Feed not found. Check URL';
}
// ...
Simply replace the city-specific functions with one starting out like this, and call it three times, one time for each specific city RSS feed URL.
From the comments:
but I'm just wondering what I will do with the 3 RSS URL variables because I can't replace rename them all to $rss_url as I will just be overwriting them until eventually the only URL will be Paris
I believe you may be suffering from a misunderstanding about PHP variable scope. Let's take this snippet as an example:
function bark($dog) {
echo 'The dog says ', $dog, ".\n";
}
$cat = 'meow';
bark($cat);
This code will emit The dog says meow. When you call the bark function with a variable, PHP takes a copy of the data* and passes it into the function as the variable name specified in the function. You don't need to name the variable the same thing both inside and outside. In fact, you can't** even see variables defined outside of a function:
function i_see_you() {
echo 'The dog heard the cat say ', $cat, ".\n";
}
$cat = 'meow';
i_see_you();
This code will emit The dog heard the cat say ., as $cat is out of scope here.
Getting back to the problem at hand, we still have three weather URLs.
$newYorkWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=USNY0996&u=f';
$londonWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=UKXX0085&u=c';
$parisWeatherSource = 'http://weather.yahooapis.com/forecastrss?p=FRXX0076&u=c';
All you need to do in order to make things work is:
echo get_current_weather($newYorkWeatherSource);
echo get_current_weather($londonWeatherSource);
echo get_current_weather($parisWeatherSource);
Inside the function, the proper variable with the proper name will have the proper data, and the right thing will happen.
*: PHP uses something called "copy-on-write", which does what you think it might do. It's completely safe to pass around variables containing large data. It will not consume unexpected amounts of memory. There's no need to use references. In fact, forget I ever said anything about references, you don't need them right now.
**: It's possible to see variables from the global scope by using the global keyword. Globals are bad practice and lead to spaghetti code. You might want to read more about variable scope in PHP.
Related
I am new to php and have just written a basic index.php that will display family tree information for an individual based on input id.
The index.php includes a file called "xml-people-list.php" which loads the information from the family tree and creates a sorted list of people.
My problem is that every time you click on a person to display their details, the included php is reloaded which causes the read from file and creation of sorted list to happen again.
Is there a way to only run this code once per session to avoid multiple loads?
I tried to look at session variables but wasn't sure if they would help or how to use them in this case or if there is another way?
Contents of "xml-people-list.php:
<?php require 'xml-load-person.php';
if (file_exists('people.xml'))
{
$people = simplexml_load_file('people.xml');
foreach ($people->person as $person)
{
$person_list[(string)$person['ID']] = strtoupper($person->FamilyName) . ", " . $person->GivenNames;
}
asort($person_list);
}
else
{
exit('Failed to open people.xml.');
}
?>
Thanks for any help!
Yes, you could use session variables. If you wanted to only parse the list once per visitor, and then "cache" the result into a session variable, you could do something like this (for a simple example):
if (!empty($_SESSION['person_list'])) {
// Here we fetch and decode the the ready list from a session variable, if it's defined:
$person_list = json_decode($_SESSION['person_list']);
}
// Otherwise we load it:
else {
require 'xml-load-person.php';
if (file_exists('people.xml'))
{
$people = simplexml_load_file('people.xml');
foreach ($people->person as $person)
{
$person_list[(string)$person['ID']] = strtoupper($person->FamilyName) . ", " . $person->GivenNames;
}
asort($person_list);
// Here we assign the ready list to a session variable (as a JSON string):
$person_list = json_encode($person_list);
$_SESSION['person_list'] = $person_list;
// Here we revert the JSON-encoded (originally SimpleXML) object into a stdClass object.
$person_list = json_decode($person_list);
}
else
{
exit('Failed to open people.xml.');
}
}
You will need to call session_start() in your file (either this one, or any other file including it, but importantly before any output is sent to the browser). Homework: Read up on sessions in PHP.
Update: Since SimpleXML objects can't be serialized, and since adding an object to $_SESSION causes serialization, I've updated the answer to json_encode/decode the object. Yes there's a bit of processing, but that'd be the case with the default serialization as well, and json_en/decode is fairly light-weight. Certainly heaps lighter than parsing XML on each page load!
Be aware that the returned object will be a stdClass object, not a SimpleXML object. I'm assuming it won't be a problem in your use case.
Maybe try require_once() function
1) First of all, try to see if your buttons are anchor tags then be sure that the href attribute is directing to # example: <a href="#">
2) try to use include_once instead of requiring
3) if you tried this and these couple solutions didn't work for you you can send the id of a person using the global $_GET variable
//this should be you URL http://localhost/projectname/index.php?person_id=1
// your href of each person should appoint to their URL
// <a href="index.php?person_id=1">
you can use this $_GET['person_id'] and store it into a variable so it will give you the id of person.
I'm developing a tool for a website and I came up with an odd problem, or better, an odd situation.
I'm using the code bellow to retrieve data from the TeamSpeak server. I use this info to build a profile on a user.
$ts3 = TeamSpeak3::factory("serverquery://dadada:dadada#dadada:1234/");
// Get the clients list
$a=$ts3->clientList();
// Get the groups list
$b=$ts3->ServerGroupList();
// Get the channels list
$c=$ts3->channelList();
Now, the odd situation is that the output of this code block:
// Get the clients list
$a=$ts3->clientList();
// Get the groups list
$b=$ts3->ServerGroupList();
// Get the channels list
$c=$ts3->channelList();
echo "<pre>";print_r($a);die();
(Notice the print_r)
Is totally different from the output of this code block:
// Get the clients list
$a=$ts3->clientList();
// Get the groups list
#$b=$ts3->ServerGroupList();
// Get the channels list
#$c=$ts3->channelList();
echo "<pre>";print_r($a);die();
What I mean is, the functions I call after clientList() (which output I store in the variable $a) are changing that variable's contents. This is, they're kind of appending their output to the variable.
I've never learned PHP professionally, I'm just trying it out... Am I missing something about this language that justifies this behavior? If I am, what can I do to stop it?
Thank you all.
You're seeing parts of the "Object" in Object Oriented Programming
$ts3 represents an Object containing all the information needed, along with some methods (or functions) that let you get data from the object. Some of these methods will do different things to the object itself, in order to retrieve additional data needed for a particular method call.
Consider the following simple Object:
Bike
color
gears
function __construct($color, $gears)
this.color = $color; this.gears = $gears
function upgrade()
this.headlight = true; this.gears = 10;
Now, when you first create it, it only has two properties:
$myBike = new Bike('red',5);
// $myBike.color = 'red';
// $myBike.gears = 5;
...but once you upgrade, properties have changed, and new ones are added.
$myBike->upgrade();
// $myBike.color = 'red';
// $myBike.gears = 10;
// $myBike.headlight = true;
Objects usually pass references rather than copying data, in order to save memory.
...but if you want to make sure that you're getting a copy that won't change (i.e. does not use data references to the $ts3 object), clone the variable.
$a = clone($ts3->clientList());
Be warned, this will effectively double the memory and processor usage for that variable.
I'm trying to make the following form's GET function to be part of a predefined variable.
Any ideas? Thanks in advance!
Let me explain a little more of what I'm really trying to do. I currently run a website concentrating on the U.S. stock market. I've created an HTML form with a method=GET. This form is used like a search box to look up stock ticker symbols. With the GET method, it places the ticker symbol at the end of the URL, and I created a quotes.php page that captures this information and displays a stock chart based on what ticker symbol is keyed into the box. For the company names, I've created a page called company.php that declares all of the variables for the company names (which happens to be a $ followed by the ticker symbol). The file, company.php, is the only file included in quotes.php.
This is where this came in: ' . $$_GET["symbol"] . '
The above code changes the GET into the variable based on what was typed into the form. I've used "die" to display an error message if someone types something into the box that doesn't match a variable in the company.php page.
I've also added into the company.php page variables for each company that will display which stock exchange each stock is listed on. These variables begin with "$ex_". So, what I was trying to do was have the symbol keyed into the box appended to "$ex_" so that it would display the corresponding stock exchange.
My questions are:
Is there a way to have what is typed into the form added to "$ex_"?
Is this an insecure way to code something like this (can it be hacked)?
Thank you all!
Rather than prefixing your variables and using variable variables (that are potentially insecure especially with user input), try this:
$ex = array(
"foo" => "bar",
...
);
if( !isset($ex[$_GET['symbol']])) die("Error: That symbol doesn't exist!");
$chosen = $ex[$_GET['symbol']];
Here's another approach:
extract($_GET, EXTR_PREFIX_ALL, "ex");
Although it's better to use it like this just to make sure there is no security issues.
extract($_GET, EXTR_SKIP);
PHP's extract() does what exactly what you want, and you should specify "ex_" as the prefix you want.
However, there are security issues and unintended consequences to using such a function blindly, so read up on the additional paragraphs following the function parameters.
Will the below achieve what you need?
$myGetVariable = $_GET['symbol'];
$ex_{$myGetVariable} = "Something";
$_GET['symbol'] = 'APPL';
if (!empty($_GET)) {
foreach ($_GET as $k => $v) {
$var = 'ex_'.$k ;
$$var=$v;
}
}
var_dump($ex_symbol);
APPL
Let me first say I've spent a day reading three google pages of articles on this subject, as well as studied this page here.
Ok, here's my dilemma. I have two functions. Both called upon via AJAX. This first one assigns a value to the variable and the second one uses that variable. Both functions are triggered by two separate buttons and need to stay that way. The AJAX and the firing off of the functions work fine, but the variable isn't passed. Here is my code:
if( $_REQUEST["subjectLine"] ) //initiate first function
{
$CID = wpCreateChimpCampaign();
echo $CID; //this works
}
if( $_REQUEST["testEmails"] ) //initiate second function
{
echo $CID; //does not return anything but should contain "apple"
wpSendChimpTest($CID);
}
function wpCreateChimpCampaign () //first function
{
$CID = "apple";
return $CID;
}
function wpSendChimpTest ($CID) //second function
{
echo $CID; //does not return anything but should contain "apple"
}
I'm open to using a class but I haven't had much luck there either. I was hoping to solve this issue without using classes. Thanks for the help in advance!
If you are making 2 separate calls to this file, it may be helpful for you to visualise this as being 2 functions in 2 totally separate files. Although they exist in the same PHP file, because they used called in different calls, they don't retain the value of the variable $CID. Once the file has run, the variable is destroyed and when you call the file again, the value is null again.
So you need to store that variable between calls. You can either store it in a database or store it in a session variable.
So call session_start(); at the beginning of the file, then rather than use $CID, just use $_SESSION['CID'];
I'm not sure where the hold up is. The code you have will work:
$CID = wpCreateChimpCampaign(); // returns 'apple'
wpSendChimpTest($CID); // echos 'apple'
The code looks fine, but are you certain that all requirements are being met so both functions execute?
In other words are you supplying values for both $_REQUEST["subjectLine"] and $_REQUEST["testEmails"]?
My site is organized into topics. Users can switch between topics on any page, at any time. I would like to be able to pass this topic along from page to page. I am guessing this should be done in a php post or get variable. I can grab the topic from the post or get variable and then run the rest of my site. However, this seems like it requires a form on every page to pass along this variable. As of now, the only way I have passed post or get variables was from forms on the previous page. I have never passed along these variables over several pages. Will I need a form on every page to pass these variables? Also, is this the standard way of doing this?
You should probably use GET, because it sounds like you're just trying to display different information, and POST is supposed to be for performing changes or actions.
If you decide to use GET variables, all you have to do is append them to the end of the link's href:
MORE BANANAS
the least overhead method of doing this would be to add some javascript that sets a cookie each time someone navigates to a new topic. This would assume you can select somehow all links that match topics (presumably trough classes)
A better method - because of compatibility,reliability and overhead - but not necessarily feasible, if a large number of links needs changing, is to use GET requests, as another poster suggested
You can create a helper function to generate your anchor tags and just append any existing query string to it, so instead of this:
Foobar
you would do this:
<?php echo anchor('page2.php','Foobar'); ?>
where your function would look like this:
/**
* Function creates an anchor tag and optionally
* appends an existing query string
* #param string $url
* #param string $txt
* #param bool $attach_qs Whether or not to follow a query string
*/
function anchor($url, $txt, $attach_qs = true)
{
$qs = '';
if ($attach_qs === true) {
$qs = (!empty($_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : '';
}
return '' . $txt . '';
}
Kolink's suggestion of placing the topic in via a PHP echo statement for every URL would certainly work. There is however, another option that I am surprised hasn't come up yet.
You could use PHPs Session Manager to store the variable. It is similar to using cookies; however, it is only temporary (limited to the session). Where a cookie can be persistent over multiple sessions.
<?php
// use this code before the page is generated, before the topic is decided.
session_start();
if (isset($_GET['topic']) && $_GET['topic'] != $_SESSION['topic']) {
// GET['topic'] is set, session variable does not match
// you may want to sanitize or limit what can be passed via ?topic=
$_SESSION['topic'] = $_GET['topic'];
} else if (isset($_SESSION['topic'])) {
// Session topic is not empty, run code to display appropriate content
} else {
// No topic is set, display default
}
?>
It's by no means the only solution, but it does give you an extra option.