I don't have that much experience with PHP and am looking for help with the following:
I am fetching data from an SQL table that has a column "countries" containing the name of a country and a column "desc" containing a comment.
On my web page I create an array out of the matching countries (based on certain criteria) in order to sort them alphabetically and to add an image in front of each of them (images have the same name as the countries).
Finally I am just echoing out this array in order to display the countries and corresponding images on the page.
All of this works well so far (using the below code).
My code:
$countries = '';
$valC = '';
$countC = 0;
foreach ($objDays->days as $days) {
if(($days->dateMatch == "Yes") && ($days->locales != "")) {
$inputC[] = explode(',', $days->locales);
$countC++;
}
}
if($countC == 0) {
$countries = " <img src='images/icons/emotion_what.png' alt='' /> No data on file for this date.";
} else {
$arrC = array_map("trim", call_user_func_array("array_merge", $inputC));
sort($arrC);
array_walk($arrC, function (&$valC) { $valC = "<img src='images/icons/flags-32/flag_" . str_replace(" ", "_", $valC) . ".png' alt='' id='c" . $valC . "' style='width:32px' /> " . $valC; } );
$countries = implode(' ', $arrC);
}
// ...
echo $countries;
Update:
The explode is no longer needed as now there is always only one country in each cell of the table.
What I am unable to do is the following:
I would like to add also the the comments from my column "desc" as a (hover) title to each country that I am echoing out.
I can fetch this via $objDays->days->desc resp. $days->desc but can't find a way to add this in.
Can someone here help me with this ?
You can store a sub array inside $inputC like that :
foreach ($objDays->days as $days) {
if(($days->dateMatch == "Yes") && ($days->locales != "")) {
$inputC[] = array(
"text" => explode(',', $days->locales),
"desc" => $days->desc
);
$countC++;
}
}
And modify your array_walk
array_walk($arrC, function (&$valC) { $valC = "<img src='images/icons/flags-32/flag_" . str_replace(" ", "_", $valC['text']) . ".png' alt='".$valC['desc']."' id='c" . $valC['text'] . "' style='width:32px' /> " . $valC['text']; } );
edit : Your trim & array_merge will be certainly broken and need to be updated.
Related
I have just learnt some basic skill for html and php and I hope someone could help me .
I had created a html file(a.html) with a form which allow students to input their name, student id, class, and class number .
Then, I created a php file(a.php) to saved the information from a.html into the info.txt file in the following format:
name1,id1,classA,1
name2,id2,classB,24
name3,id3,classA,15
and so on (The above part have been completed with no problem) .
After that I have created another html file(b.html), which require user to enter their name and id in the form.
For example, if the user input name2 and id2 in the form, then the php file(b.php) will print the result:
Class: classB
Class Number: 24
I have no idea on how to match both name and id at the same time in the txt file and return the result in b.php
example data:
name1,id1,classA,1
name2,id2,classB,24
name3,id3,classA,15
<?php
$name2 = $_POST['name2'];
$id2 = $_POST['id2'];
$data = file_get_contents('info.txt');
if($name2!='')
$konum = strpos($data, $name2);
elseif($id2!='')
$konum = strpos($data, $id2);
if($konum!==false){
$end = strpos($data, "\n", $konum);
$start = strrpos($data, "\n", (0-$end));
$row_string = substr($data, $start, ($end - $start));
$row = explode(",",$row_string);
echo 'Class : '.$row[2].'<br />';
echo 'Number : '.$row[3].'<br />';
}
?>
Iterate through lines until you find your match. Example:
<?php
$csv=<<<CSV
John,1,A
Jane,2,B
Joe,3,C
CSV;
$data = array_map('str_getcsv', explode("\n", $csv));
$get_name = function($number, $letter) use ($data) {
foreach($data as $row)
if($row[1] == $number && $row[2] == $letter)
return $row[0];
};
echo $get_name('3', 'C');
Output:
Joe
You could use some simple regex. For example:
<?php
$search_name = (isset($_POST['name'])) ? $_POST['name'] : exit('Name input required.');
$search_id = (isset($_POST['id'])) ? $_POST['id'] : exit('ID input required.');
// First we load the data of info.txt
$data = file_get_contents('info.txt');
// Then we create a array of lines
$lines = preg_split('#\\n#', $data);
// Now we can loop the lines
foreach($lines as $line){
// Now we split the line into parts using the , seperator
$line_parts = preg_split('#\,#', $line);
// $line_parts[0] contains the name, $line_parts[1] contains the id
if($line_parts[0] == $search_name && $line_parts[1] == $search_id){
echo 'Class: '.$line_parts[2].'<br>';
echo 'Class Number: '.$line_parts[3];
// No need to execute the script any further.
break;
}
}
You can run this. I think it is what you need. Also if you use post you can change get to post.
<?php
$name = $_GET['name'];
$id = $_GET['id'];
$students = fopen('info.txt', 'r');
echo "<pre>";
// read each line of the file one by one
while( $student = fgets($students) ) {
// split the file and create an array using the ',' delimiter
$student_attrs = explode(',',$student);
// first element of the array is the user name and second the id
if($student_attrs[0]==$name && $student_attrs[1]==$id){
$result = $student_attrs;
// stop the loop when it is found
break;
}
}
fclose($students);
echo "Class: ".$result[2]."\n";
echo "Class Number: ".$result[3]."\n";
echo "</pre>";
strpos can help you find a match in your file. This script assumes you used line feed characters to separate the lines in your text file, and that each name/id pairing is unique in the file.
if ($_POST) {
$str = $_POST["name"] . "," . $_POST["id"];
$file = file_get_contents("info.txt");
$data = explode("\n", $file);
$result = array();
$length = count($data);
$i = 0;
do {
$match = strpos($data[$i], $str, 0);
if ($match === 0) {
$result = explode(",", $data[$i]);
}
} while (!$result && (++$i < $length));
if ($result) {
print "Class: " . $result[2] . "<br />" . "Class Number: " . $result[3];
} else {
print "Not found";
}
}
This script displays the categories of a post, but excludes the ones that the user doesn't want to show:
function exclude_post_categories($excl='', $spacer=' ') {
$categories = get_the_category($post->ID);
if (!empty($categories)) {
$exclude = $excl;
$exclude = explode(",", $exclude);
$thecount = count(get_the_category()) - count($exclude);
foreach ($categories as $cat) {
$html = '';
if (!in_array($cat->cat_ID, $exclude)) {
$html .= '<a href="' . get_category_link($cat->cat_ID) . '" ';
$html .= 'title="' . $cat->cat_name . '">' . $cat->cat_name . '</a>';
if ($thecount > 1) {
$html .= $spacer;
}
$thecount--;
echo $html;
}
}
}
}
The fuctions is triggered like this.
<?php exclude_post_categories('5', ', ');
So if a post has the categories: 1,2,3,4,5 than only 1,2,3,4 are echoed.
The script works great for the posts that have the category that is excluded (5).
The problem lies with the posts that don't have that category.
So if a post has the categories: 1,2,3,4 that those are echoed but with less commas than needed: 1,2,34
$thecount variable is always calculated wrong for the posts that don't have the category that has to be excluded.
Try something like this:
$existing = get_the_category();
$newcategories = array_udiff($existing,$exclude,function($e,$x) {
return $e->cat_ID != $x;
});
$as_links = array_map(function($c) {
return '<a href="'.get_category_link($c->cat_ID).'" '
.'title="'.$cat->cat_name.'">'.$cat->cat_name.'</a>';
},$newcategories);
echo implode($spacer, $as_links);
This will first strip out categories whose IDs are in the $exclude array, then convert each category to a category link, before outputting them with the separator.
EDIT: Slightly mis-read the question. This expects $exclude to be an array. Put the following line at the start:
if( !is_array($exclude)) $exclude = array($exclude);
To make it support single-value inputs as well - this way you can either specify one or many categories to exclude.
Found a better solution to the problem here: http://css-tricks.com/snippets/wordpress/the_category-excludes/#comment-1583708
function exclude_post_categories($exclude="",$spacer=" ",$id=false){
//allow for specifiying id in case we
//want to use the function to bring in
//another pages categories
if(!$id){
$id = get_the_ID();
}
//get the categories
$categories = get_the_category($id);
//split the exclude string into an array
$exclude = explode(",",$exclude);
//define array for storing results
$result = array();
//loop the cats
foreach($categories as $cat){
if(!in_array($cat->cat_ID,$exclude)){
$result[] = "$cat->name";
}
}
//add the spacer
$result = implode($spacer,$result);
//print out the result
echo $result;
}
First and foremost, forgive me if my language is off - I'm still learning how to both speak and write in programming languages. How I can retrieve an entire object from an array in PHP when that array has several key, value pairs?
<?php
$quotes = array();
$quotes[0] = array(
"quote" => "This is a great quote",
"attribution" => "Benjamin Franklin"
);
$quotes[1] = array(
"quote" => "This here is a really good quote",
"attribution" => "Theodore Roosevelt"
);
function get_random_quote($quote_id, $quote) {
$output = "";
$output = '<h1>' . $quote["quote"] . '.</h1>';
$output .= '<p>' . $quote["attribution"] . '</p>';
return $output;
} ?>
<?php
foreach($quotes as $quote_id => $quote) {
echo get_random_quote($quote_id, $quote);
} ?>
Using array_rand and var_dump I'm able to view the item in the browser in raw form, but I'm unable to actually figure out how to get each element to display in HTML.
$quote = $quotes;
$random_quote = array_rand($quote);
var_dump($quote[$random_quote]);
Thanks in advance for any help!
No need for that hefty function
$random=$quotes[array_rand($quotes)];
echo $random["quote"];
echo $random["attribution"];
Also, this is useless
<?php
foreach($quotes as $quote_id => $quote) {
echo get_random_quote($quote_id, $quote);
} ?>
If you have to run a loop over all the elements then why randomize hem in the first place? This is circular. You should just run the loop as many number of times as the quotes you need in output. If you however just need all the quotes but in a random order then that can simply be done in one line.
shuffle($quotes); // this will randomize your quotes order for loop
foreach($quotes as $qoute)
{
echo $quote["quote"];
echo $quote["attribution"];
}
This will also make sure that your quotes are not repeated, whereas your own solution and the other suggestions will still repeat your quotes randomly for any reasonably sized array of quotes.
A simpler version of your function would be
function get_random_quote(&$quotes)
{
$quote=$quotes[array_rand($quotes)];
return <<<HTML
<h1>{$quote["quote"]}</h1>
<p>{$quote["attribution"]}</p>
HTML;
}
function should be like this
function get_random_quote($quote_id, $quote) {
$m = 0;
$n = sizeof($quote)-1;
$i= rand($m, $n);
$output = "";
$output = '<h1>' . $quote[$i]["quote"] . '.</h1>';
$output .= '<p>' . $quote[$i]["attribution"] . '</p>';
return $output;
}
However you are not using your first parameter-$quote_id in the function. you can remove it. and call function with single parameter that is array $quote
Why don't you try this:
$quote = $quotes;
$random_quote = array_rand($quote);
$random = $quote[$random_quote];
echo '<h1>' . $random["quote"] . '.</h1><br>';
echo '<p>' . $random["attribution"] . '</p>';
Want to create a function:
echo get_random_quote($quotes);
function get_random_quote($quotes) {
$quote = $quotes;
$random_quote = array_rand($quote);
$random = $quote[$random_quote];
return '<h1>' . $random["quote"] . '.</h1><br>'.'<p>' . $random["attribution"] . '</p>';
}
First, you dont need the $quote_id in get_random_quote(), should be like this:
function get_random_quote($quote) {
$output = "";
$output = '<h1>' . $quote["quote"] . '.</h1>';
$output .= '<p>' . $quote["attribution"] . '</p>';
return $output;
}
And I cant see anything random that the function is doing. You are just iterating through the array:
foreach($quotes as $quote_id => $quote) {
echo get_random_quote( $quote);
}
According to http://php.net/manual/en/function.array-rand.php:
array_rand() Picks one or more random entries out of an array, and
returns the key (or keys) of the random entries.
So I guess $quote[$random_quote] should return your element, you can use it like:
$random_quote = array_rand($quotes);
echo get_random_quote($quote[$random_quote]);
The following code produces each result as text. I would like to add some html to each result, to change it from regular text to an href tag:
while (!$recordSet->EOF()) {
if ($pclass_name_list == '') {
$pclass_name_list .= $recordSet->fields['class_name'];
} else {
$pclass_name_list .= ',' . $recordSet->fields['class_name'];
}
$recordSet->MoveNext();
}
The above produces Result 1, Result 2. I'd like to change these to
Result 1
Result 2
etc..
If you are doing a simple addition of content into a string, you can either wrap the variable in curly braces and include it in a string that has double quotes (as below), or you can use the sprintf function to merge content into a template.
$pclass_name_list = array();
while (!$recordSet->EOF()) {
$current_class_name = $recordSet->fields['class_name'];
$pclass_name_list[] = "{$current_class_name}";
$recordSet->MoveNext();
}
$pclass_name_list = implode(", ", $pclass_name_list);
Maybe:
if ($pclass_name_list == '') {
$pclass_name_list .= '' . $recordSet->fields['class_name'] . '';
} else {
$pclass_name_list .= ', ' . $recordSet->fields['class_name'] . '';
}
The XML feed is located at: http://xml.betclick.com/odds_fr.xml
I need a php loop to echo the name of the match, the hour, and the bets options and the odds links.
The function will select and display ONLY the matchs of the day with streaming="1" and the bets type "Ftb_Mr3".
I'm new to xpath and simplexml.
Thanks in advance.
So far I have:
<?php
$xml_str = file_get_contents("http://xml.betclick.com/odds_fr.xml");
$xml = simplexml_load_string($xml_str);
// need xpath magic
$xml->xpath();
// display
?>
Xpath is pretty simple once you get the hang of it
you basically want to get every match tag with a certain attribute
//match[#streaming=1]
will work pefectly, it gets every match tag from underneath the parent tag with the attribute streaming equal to 1
And i just realised you also want matches with a bets type of "Ftb_Mr3"
//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]
This will return the bet node though, we want the match, which we know is the grandparent
//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]/../..
the two dots work like they do in file paths, and gets the match.
now to work this into your sample just change the final bit to
// need xpath magic
$nodes = $xml->xpath('//match[#streaming=1]/bets/bet[#code="Ftb_Mr3"]/../..');
foreach($nodes as $node) {
echo $node['name'].'<br/>';
}
to print all the match names.
I don't know how to work xpath really, but if you want to 'loop it', this should get you started:
<?php
$xml = simplexml_load_file("odds_fr.xml");
foreach ($xml->children() as $child)
{
foreach ($child->children() as $child2)
{
foreach ($child2->children() as $child3)
{
foreach($child3->attributes() as $a => $b)
{
echo $a,'="',$b,"\"</br>";
}
}
}
}
?>
That gets you to the 'match' tag which has the 'streaming' attribute. I don't really know what 'matches of the day' are, either, but...
It's basically right out of the w3c reference:
http://www.w3schools.com/PHP/php_ref_simplexml.asp
I am using this on a project. Scraping Beclic odds with:
<?php
$match_csv = fopen('matches.csv', 'w');
$bet_csv = fopen('bets.csv', 'w');
$xml = simplexml_load_file('http://xml.cdn.betclic.com/odds_en.xml');
$bookmaker = 'Betclick';
foreach ($xml as $sport) {
$sport_name = $sport->attributes()->name;
foreach ($sport as $event) {
$event_name = $event->attributes()->name;
foreach ($event as $match) {
$match_name = $match->attributes()->name;
$match_id = $match->attributes()->id;
$match_start_date_str = str_replace('T', ' ', $match->attributes()->start_date);
$match_start_date = strtotime($match_start_date_str);
if (!empty($match->attributes()->live_id)) {
$match_is_live = 1;
} else {
$match_is_live = 0;
}
if ($match->attributes()->streaming == 1) {
$match_is_running = 1;
} else {
$match_is_running = 0;
}
$match_row = $match_id . ',' . $bookmaker . ',' . $sport_name . ',' . $event_name . ',' . $match_name . ',' . $match_start_date . ',' . $match_is_live . ',' . $match_is_running;
fputcsv($match_csv, explode(',', $match_row));
foreach ($match as $bets) {
foreach ($bets as $bet) {
$bet_name = $bet->attributes()->name;
foreach ($bet as $choice) {
// team numbers are surrounded by %, we strip them
$choice_name = str_replace('%', '', $choice->attributes()->name);
// get the float value of odss
$odd = (float)$choice->attributes()->odd;
// concat the row to be put to csv file
$bet_row = $match_id . ',' . $bet_name . ',' . $choice_name . ',' . $odd;
fputcsv($bet_csv, explode(',', $bet_row));
}
}
}
}
}
}
fclose($match_csv);
fclose($bet_csv);
?>
Then loading the csv files into mysql. Running it once a minute, works great so far.