I have a field called links that accepts a list of URLs separated by a comma, e.g. 'www.bbc.co.uk, www.itv.co.uk'
When I then output the contents of the field, I wrap it in code like this:
<li><a href='http://<?php echo htmlout($name['links']); ?>'><?php echo htmlout($name['links']); ?></a></li>
This works fine when a single link is added but when there is more then one, then it causes problems.
If for instance I have two links, one is www.bbc.co.uk and one is www.itv.co.uk and then I hover over the link (it is a single link of instead of two), it shows as:
http://www.ts.co.uk%2C%20www.bbc.co.uk/
Now I'm thinking that because they are separated by commas, there may be some way to use this as a hook to split the URLs up but I am not sure if this is possible.
Any help is appreciated. Thanks
EDIT BELOW
Added some code below as I already have an array. Can I have an array within an array? Should I in this case? Where should I drop the suggested code in?
INDEX.PHP (Controller)
include $_SERVER['DOCUMENT_ROOT'] . '/includes/db.inc.php';
try
{
$sql = "SELECT player.id, player.name AS name, age, position, height, weight, GROUP_CONCAT(distinct previousclubs.name) previousclubs,
satscore, gpa, GROUP_CONCAT(distinct link) link, email
FROM player INNER JOIN playerpreviousclubs
ON player.id = playerid
INNER JOIN previousclubs
ON previousclubid = previousclubs.id
INNER JOIN links
ON links.playerid = player.id
WHERE email = '$username'";
$result = $pdo->query($sql);
}
catch (PDOException $e)
{
$error = 'Error fetching details: ' . $e->getMessage();
include 'error.html.php';
exit();
}
foreach ($result as $row)
{
$names[] = array(
'id' => $row['id'],
'name' => $row['name'],
'age' => $row['age'],
'position' => $row['position'],
'height' => $row['height'],
'weight' => $row['weight'],
'previousclubs' => $row['previousclubs'],
'satscore' => $row['satscore'],
'gpa' => $row['gpa'],
'links' => $row['link'],
'email' => $row['email']
);
}
include 'profiles.html.php';
And my template looks like this currently:
PROFILES.HTML.PHP
<p>Welcome <?php echo $row['name'] ?> . Below are your profile details:</p>
<?php foreach ($names as $name): ?>
<form action="" method="post">
<ol>
<li class="listleft">Name:</li>
<li><?php echo htmlout($name['name']); ?></li>
<li class="listleft">Age:</li>
<li><?php echo htmlout($name['age']); ?></li>
<li class="listleft">Position:</li>
<li><?php echo htmlout($name['position']); ?></li>
<li class="listleft">Height:</li>
<li><?php echo htmlout($name['height']); ?></li>
<li class="listleft">Weight:</li>
<li><?php echo htmlout($name['weight']); ?></li>
<li class="listleft">Previous Clubs:</li>
<li><?php echo htmlout($name['previousclubs']); ?></li>
<li class="listleft">GPA:</li>
<li><?php echo htmlout($name['satscore']); ?></li>
<li class="listleft">SAT Score:</li>
<li><?php echo htmlout($name['gpa']); ?></li>
<li class="listleft">Links:</li>
<li><a href='http://<?php echo htmlout($name['links']); ?>'><?php echo htmlout($name['links']); ?></a></li>
</ol>
</form>
<?php endforeach; ?>
$links = explode(',', $links);
foreach($links as $link) {
echo '<li>'.$link.'</li>';
}
You'll need to explode them, then loop through them.
$links = explode(',', $name['links']);
Then in your view:
foreach ($links as $link) {
echo '<li>'.$link.'</li>';
}
You can easily split string using explode function:
// split string by comma, returns array
$linksArray = explode(',', $links);
foreach($linksArray as $link) {
echo $link; // print each link etc
}
You'd be better to explode the string into an array, then loop around the array to output the data. Personally, I find arrays much easier to work with than a string. For example:
$links = explode(',', $links);
foreach($links as $link) {
?>
<li><?php echo htmlout($link); ?></li>
<?php
}
Related
I am trying to utilize the Bitcoin Charts API to display bitcoin value in all currencies as list items.
Currently I am repeating this PHP snippet in each list item:
<li class="myClass">
<?php
foreach(json_decode(file_get_contents("http://api.bitcoincharts.com/v1/markets.json")) as $item)
if($item->symbol == 'localbtcPLN') break;
printf("\t%s\nPLN", $item->avg);
?>
</li>
How can I simplify this so that the code is only calling the JSON file once?
Thanks for your help.
As per Vishal's assistance, I tried this:
<?php $all_data = json_decode(file_get_contents("http://api.bitcoincharts.com/v1/markets.json"),true);
foreach ($all_data as $data)
{
?><li class="pure-menu-item pure-menu-disabled">
<?php
echo $data['ask'];//use the keyname to get the value
echo ' ';
echo $data['currency'];
?>
</li>
<?php
}
?>
However, it is outputting too much data, including empty values.
Using what I've learned from Florian and Vishal, I have attempted the following snippet, which outputted the data perfectly with the caveat of some duplicated currencies.
<?php $all_data = json_decode(file_get_contents("http://api.bitcoincharts.com/v1/markets.json"),true);
foreach ($all_data as $data)
{
if(trim($data['avg']) != "")//check if value not empty
{
?><li class="pure-menu-item pure-menu-disabled">
<?php
echo $data['avg']; //use the keyname to get the value
echo ' ';
echo $data['currency'];
?>
</li>
<?php
}
}
?>
you can run a foreach loop
<ol>
<?php $all_data = json_decode(file_get_contents("http://api.bitcoincharts.com/v1/markets.json"),true);
foreach ($all_data as $data)
{
if(trim($data['currency']) != "")//check if value not empty
{
?><li>
<?php echo $data['bid'];//use the keyname to get the value ?>
</li>
<?php
}
}
?>
</ol>
I think you want to show values in a certain order.
First, store the result of json_decode() in an array like #Vishal Wadhawan said.
$all_data = json_decode(file_get_contents("http://api.bitcoincharts.com/v1/markets.json"),true);
Next, make a new array where you will store only symbol and avg:
$myvalues = array();
foreach ($all_data as $data)
{
$myvalues[$data['symbol']] = $data['avg'];
}
After that, you can use $myvalues to display avg like that:
<li class="myClass">
<?php echo $myvalues['localbtcPLN'] . ' PLN'; ?>
</li>
You can also store the 'currency' value:
$myvalues[$data['symbol']] = array(
'avg' => $data['avg'],
'currency' => $data['currency'],
);
And access it with:
<li class="myClass">
<?php echo $myvalues['localbtcPLN']['avg'] . ' ' . $myvalues['localbtcPLN']['currency']; ?>
</li>
I'm working on a simple CMS for a pet project. I currently have a JSON string that contains a list of page ID's and Parent page ID's for a menu structure.
I want to now convert this string into a nested or hierarchical list (ordered list).
I've tried looking looping through but seem to have ended up with an overly complex range of sub classes. I'm struggling to find a suitable light-weight solution in PHP.
Here's the JSON:
**[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]**
Here's the desired output:
<ol>
<li>3
<ol>
<li>4</li>
<ol>
<li>5</li>
</ol>
</ol>
</li>
<li>6</li>
<li>2</li>
<li>4</li>
</ol>
Is there anything built in to PHP that can simplify this process? Has anyone had any experience of this before?
I'm a newbie to PHP and SE. Looking forward to hearing from you.
Here's my current progress (it's not working too well)
<ol>
<?php
$json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
$decoded = json_decode($json);
$pages = $decoded;
foreach($pages as $page){
$subpages = $decoded->children;
echo "<li>".$page->id."</li>";
foreach($subpages as $subpage){
echo "<li>".$subpage->id."</li>";
}
}
?>
</ol>
You can use recursion to get deep inside the data. If the current value is an array then recursion again. Consider this example:
$json_string = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
$array = json_decode($json_string, true);
function build_list($array) {
$list = '<ol>';
foreach($array as $key => $value) {
foreach($value as $key => $index) {
if(is_array($index)) {
$list .= build_list($index);
} else {
$list .= "<li>$index</li>";
}
}
}
$list .= '</ol>';
return $list;
}
echo build_list($array);
Using a function that can recursively go through your JSON, you can get the functionality you wish. Consider the following code: (this only accounts for an attribute of id as getting listed, as your desired code shows)
$json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
function createOLList($group) {
$output = (is_array($group)) ? "<ol>" : "";
foreach($group as $attr => $item) {
if(is_array($item) || is_object($item)) {
$output .= createOLList($item);
} else {
if($attr == "id") {
$output .= "<li>$item</li>";
}
}
}
$output .= (is_array($group)) ? "</ol>" : "";
return $output;
}
print(createOLList(json_decode($json)));
This will produce the following HTML output.
<ol>
<li>3</li>
<ol>
<li>4</li>
<ol>
<li>5</li>
</ol>
</ol>
<li>6</li>
<li>2</li>
<li>4</li>
</ol>
What you're looking for is called recursion, which can be done by a function calling itself.
If you solved once to list all nodes of the list in one function, you can then apply the same function for all child-lists. As then those child-lists will do the same on their children, too.
call_user_func(function ($array, $id = 'id', $list = 'children') {
$ul = function ($array) use (&$ul, $id, $list) {
echo '<ul>', !array_map(function ($child) use ($ul, $id, $list) {
echo '<li>', $child[$id], isset($child[$list]) && $ul($child[$list])
, '</li>';
}, $array), '</ul>';
};
$ul($array);
}, json_decode('[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},
{"id":2},{"id":4}]', TRUE));
As this example shows, the $ul function is called recursively over the list and all children. There are other solutions, but most often recursion is a simple method here to get the job done once you've wrapped your head around it.
Demo: https://eval.in/153471 ; Output (beautified):
<ul>
<li>3
<ul>
<li>4
<ul>
<li>5</li>
</ul>
</li>
</ul>
</li>
<li>6</li>
<li>2</li>
<li>4</li>
</ul>
<?php
$json_array = array();
array_push($json_array, array(
'id' => 3,
'children' => array(
'id' => 4,
'children' => array(
'id' => 5,
)
)
));
array_push($json_array, array('id' => 6));
array_push($json_array, array('id' => 2));
array_push($json_array, array('id' => 4));
//your json object
$json_object = json_encode($json_array);
//echo $json_object;
//here is where you decode your json object
$json_object_decoded = json_decode($json_object,true);
//for debug to see how your decoded json object looks as an array
/*
echo "<pre>";
print_r($json_object_decoded);
echo "</pre>";
*/
echo "<ol>";
foreach($json_object_decoded as $node){
if(isset($node['id'])){
echo "<li>" . $node['id'];
if(isset($node['children'])){
echo "<ol>";
echo "<li>" . $node['children']['id'] . "</li>";
if(isset($node['children'])){
echo "<ol>";
echo "<li>" . $node['children']['children']['id'] . "</li>";
echo "</ol>";
}
echo "</ol>";
}
echo "</li>";
}
}
echo "</ol>";
?>
I have found that i have to fix or simplify almost every of the functions above.
So here i came with something simple and working, still recursion.
function build_list($array) {
$list = '<ul>';
foreach($array as $key => $value) {
if (is_array($value)) {
$list .= "<strong>$key</strong>: " . build_list($value);
} else {
$list .= "<li><strong>$key</strong>: $value</li>";
}
}
$list .= '</ul>';
return $list;
}
build_list(json_encode($json_string),true);
I have an array I got from a mysql query
key1 key2 value
10 2 url_A
10 1 url_B
9 3 url_C
9 2 url_D
9 1 url_E
7 1 url_f
I want to put it into this format in html.
<ul class="main">
<li id="10">
<ul>
<li>url_A</li>
<li>url_B</li>
</ul>
</li>
<li id="9">
<ul>
<li>url_C</li>
<li>url_D</li>
<li>url_E</li>
</ul>
</li>
<li id="7">
<ul>
<li>url_F</li>
</ul>
</li>
</ul>
How can I use foreach() (or is there a better way) and get this done?
This is HOW I get my array now.
$result = mysql_query($sql) or die(mysql_error());
while($data = mysql_fetch_object($result)){
$Items[] = array(
'key1' => $data->pID1,
'key2' => $data->ID2,
'value' => $data->urlString,
);
}
You can build the array with two keys as well:
while ($data = mysql_fetch_object($result)) {
$Items[$data->pID1][$data->ID2] = $data->urlString;
}
And then assemble the whole thing together:
echo '<ul class="main">';
foreach ($Items as $pid => $data) {
printf('<li id="%s"><ul>', $pid);
foreach ($data as $item) {
printf('<li>%s</li>', htmlspecialchars($item, ENT_QUOTES, 'UTF-8'));
}
echo '</ul></li>';
}
echo '</ul>';
Btw, unless you're using HTML5, you shouldn't use numeric identifiers for your elements.
<?php
$arr[10][2] = "url_A";
$arr[10][1] = "url_B";
$arr[9][3] = "url_C";
$arr[9][2] = "url_D";
$arr[9][1] = "url_E";
$arr[7][1] = "url_F";
?>
<ul class="main">
<?php
foreach ($arr as $key => $val) {
echo "<li id='$key'>\n\t<ul>";
foreach ($val as $item_key => $item) {
echo "\n\t<li>$item</li>";
}
echo "\n\t</ul>\n</li>\n";
}
?>
</ul>
I want to run two seperate foreach loops on the one page, but only write my SQL once. For example see the below code, only the ul with the id of first runs, the second ul is empty.
<?php
$mylist = 'SELECT * FROM myTable';
$showlist = $pdo->prepare($mylist);
$showlist->execute();
?>
<ul id="first">
<?php foreach ($showlist as $rowid):;?>
<li><?php echo $rowid['id'] ?></li>
<?php endforeach; ?>
</ul>
<ul id="second">
<?php foreach ($showlist as $rowname):;?>
<li><?php echo $rowname['name'] ?></li>
<?php endforeach; ?>
</ul>
I thought renaming the as would allow me to use it again but this doesn't seem to be the case? What is the best approach here?
try:
<?php
$mylist = 'SELECT * FROM myTable';
$showlist = $pdo->prepare($mylist);
$showlist->execute();
$result = $showlist->fetchAll();
foreach ($result as $rowid) {
// do stuff
}
foreach ($result as $rowname) {
// do stuff
}
You'd need to stack your elements in an extra array first:
$mylist = 'SELECT * FROM myTable';
$showlist = $pdo->prepare($mylist);
$showlist->execute();
$rows = array();
foreach($showlist as $row) {
array_push($rows, $row);
}
echo "<ul>";
foreach($rows as $row) {
echo "<li>".$row['id']."</li>";
}
echo "</ul><ul>";
foreach($rows as $row) {
echo "<li>".$row['name']."</li>";
}
echo "</ul>";
I am trying to make a php navbar sort of thing. I have the html code and what I want to do is to use a php dictionary ("Home"=>"http://www.domain.com/") and turn it into html code.
<ul>
<?php foreach ($links as $title => $url): ?>
<li><?php echo htmlentities($title); ?></li>
<?php endforeach; ?>
</ul>
foreach($arr as $key=>$value) {
// your code here
}
I have no idea how you want to make your navbar, but with any knowledge of HTML you should be able to go from here.
foreach (dict as $key => $value){
echo "<a href='$value'>$key</a>";
}
Fastest
<?php
foreach($array as $name => $link){
echo '',$name,'\n';
}
?>
Easier to read and understand but slower
<?php
foreach($array as $name => $link){
echo "<a href='$link'>$name</a>\n";
}
?>
I don't know if i understand the question but you can use an hash like this:
<?php
$navBar = array(
"Home" => "http://www.domain.com/",
"Info" => "http://www.domain.com/info/",
);
foreach($navBar as $key => $val){
echo "<li>$key => $val<li>";
}
?>