I have following code:
SELECT q21, q21coding AS Description FROM `tresults_acme` WHERE q21 IS NOT NULL AND q21 <> '' ORDER BY q21coding
It brings back the following (excerpt):
Text Description
Lack of up to date equal pay cases&legislation - t... Content needs updating
The intranet could contain more "up to date traini... Content needs updating
Poorly set out. It is hard to find things. Difficulty in navigating/finding content
Only use the intranet as a necessity. Will ask my ... Difficulty in navigating/finding content
Now, I'd like to display this in a table on a PHP page but am having some problems because of the way I'd like it displayed, it needs to be as follows:
Content needs updating
----------------------
[List all the comments relating to this description]
Difficulty in navigating/finding content
----------------------------------------
[List all the comments relating to this description]
and so on.
Now I think it is a For Each loop in PHP but I am having terrible difficulty getting my head around this - any ideas and suggestions very very welcome!
Thanks,
Simple approach
Set prev_desc to NULL
For each row print text
If description is not equal to prev_desc prepend with the description for the new "section" and set prev_desc <- description
E.g.1 (untested!),
$prev_desc = null;
while ($row = mysql_fetch_assoc(...)) {
if ($prev_desc != $row['description']) {
print '<h1>' . $row['description'] . '</h1>';
$prev_desc = $row['description'];
}
print $row['text'] . '<br />'; // Formatting needed
}
Note: You must keep the ORDER BY <description-column> in order to have rows "grouped". Otherwise this simple approach will not work.
Less presentation-specific approach
I could be considered more "clean" to create some kind of 2D container to "categorize" the extracted data, e.g.,
$items = array(
'Content needs updating' => array(
'Lack of ...',
'The intra...'
),
...
);
You could then loop over these items like so1:
foreach ($items as $desc => $texts) {
print '<h1>' . $desc . '</h1>';
foreach ($texts as $text) {
print $text . '<br />';
}
}
1 As #bobince has noted, make sure that content going directly into the final HTML is properly escaped, see e.g. htmlspecialchars().
You just need to keep track of which heading you last displayed. I don't know which library you're using for database access, so the details of how you access columns/rows will be slightly different, but here it is in kind-of pseudocode:
$lastHeading = '';
foreach($rows as $row)
{
if ($lastHeading != $row['Description'])
{
if ($lastHeading != '')
echo '</ul>';
$lastHeading = $row['Description'];
echo "<h1>$lastHeading</h1>";
echo '<ul>';
}
echo '<li>'.$row['Text'].'</li>';
}
if ($lastHeading != '')
echo '</ul>';
This has the added feature of putting comments in a <ul>, not sure if that's required for you or not.
This works because you've sorted by the "description" column. That means you know that all of the rows with the same "description" will come together.
you can either create multiple queries for each of the sections or loop over the data multiple times and filter based on the type of description using php.
$descriptions = array('Content needs updating','Difficulty in navigating/finding content');
$rows = <fetch all rows from the query>;
foreach($descriptions as $description)
{
echo '<h1>',$description,'</h1>';
foreach($rows as $row)
{
if ($row['description'] == $description)
{
echo $row['text'],'<br />';
}
}
}
Related
Main purpose is to get all categories listing from database by passing variables to url and show it to the main page.here i have omitted some code bt i tried to clarify.
1.can I exclude encodeHtml() method, too difficult for me to understand
2.i am not getting specially this part of code and having my head for 4 days
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";//here id is 'category id' from database. this full line will echo what?
echo Helper::getActive(array('category' => $cat['id']));//it will output what ?
echo ">";
echo Helper::encodeHtml($cat['name']);//as from ur answer can we omit encodeHTML() method and use htmlspecialchars($cat['name']); instead ?
echo "</a>
3.any easier solution will be more appreciated
in our database we have 'id' and 'name' of catagory listing
please check below for reference
/*below is the code in header section of template */
<?php
$objCatalogue = new Catalogue();// creating object of Catalogue class
$cats = $objCatalogue->getCategories(); // this gets all categories from database
<h2>Categories</h2>
<?php
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";
echo Helper::getActive(array('category' => $cat['id']));
echo ">";
echo Helper::encodeHtml($cat['name']);
echo "</a></li>";
}
?>
/*below is the helper class which is Helper.php */
public static function getActive($page = null) {
if(!empty($page)) {
if(is_array($page)) {
$error = array();
foreach($page as $key => $value) {
if(Url::getParam($key) != $value) //getParam takes name of the parameter and returns us the value by $_GET
{
array_push($error, $key);
}
}
return empty($error) ? " class=\"act\"" : null;
}
}
//CHECK THIS LINE BROTHER
return $page == Url::currentPage() ? " class=\"act\"" : null;// url::currentPage returns the current page but what is 'class =act ' :(
}
public static function encodeHTML($string, $case = 2) {
switch($case) {
case 1:
return htmlentities($string, ENT_NOQUOTES, 'UTF-8', false);
break;
case 2:
$pattern = '<([a-zA-Z0-9\.\, "\'_\/\-\+~=;:\(\)?&#%![\]#]+)>';
// put text only, devided with html tags into array
$textMatches = preg_split('/' . $pattern . '/', $string);
// array for sanitised output
$textSanitised = array();
foreach($textMatches as $key => $value) {
$textSanitised[$key] = htmlentities(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
}
foreach($textMatches as $key => $value) {
$string = str_replace($value, $textSanitised[$key], $string);
}
return $string;
break;
}
}
Firstly, in your URL (/?page=catalogue&category=) you don't need to put &, as this is an HTML entity for actually displaying an ampersand in a web page. Just use /?page=catalogue&category=.
Secondly, you can use urlencode() to prepare strings for sending in the URL, and urldecode() on the other end.
In answer to your first point you just need to make sure that ANYTHING from the user (whether via $_POST or $_GET) is sanitized, prior to being used in code, output to a web page, or used in database queries. Use htmlspecialchars() for cleaning before outputting to a web page, and prepared statements prior to entering user input into a query.
In answer to your second point please read the documentation in the links I have provided above. Just reading the documentation on htmlspecialchars() will help you a lot.
Hope this helps.
Alright then.
<?php
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";
echo Helper::getActive(array('category' => $cat['id']));
echo ">";
echo Helper::encodeHtml($cat['name']);
echo "</a></li>";
}
?>
Im just going to kindof skim through it, because honestly if you really want to learn all this you should probably google the shit out of every piece of code you don't understand, it's the way we all learn things.
< ?php announces some php script to follow. And as you can see, there does follow some php code after.
foreach is a way of getting each element from an array or list and doing something to that element.
echo sends whatever string comes after it to the page, or whatever is listening to its output. In this case, it looks like the echo's are printing some <li> list item with an <a> anchor in it.
Helper::getActive(): Helper is some class that is defined somewhere, :: is syntax for calling a static function that belongs to the class (Helper in this case). getActive is the function name.
array('category' => $cat['id'] is a piece of code that creates an array with 1 element in it, being one with key 'category' and a value of whatever is in $cat['id'].
By looking at getActive: it looks like it's a function that checks the url for some value so it can determine which page to display. It also checks if the url contains errors.
By lookingat encodeHtml(): it looks like it's a function that makes sure that whatever text you're trying to put on the screen, isn't something that could cause harm. In some situations, people will try to make your server print javascript that could harm the user (by sending personal data to somewhere). The encodeHtml() will ensure that no such thing can be done by stripping certain characters from the text you're about to send to the page.
USE GOOGLE.
I am parsing through an XML document and getting the values of nested tags using asXML(). This works fine, but I would like to move this data into a MySQL database whose columns match the tags of the file. So essentially how do I get the tags that asXML() is pulling text from?
This way I can eventually do something like: INSERT INTO db.table (TheXMLTag) VALUES ('XMLTagText');
This is my code as of now:
$xml = simplexml_load_file($target_file) or die ("Error: Cannot create object");
foreach ($xml->Message->SettlementReport->SettlementData as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
foreach ($xml->Message->SettlementReport->Order as $main ){
$value = $main->asXML();
echo '<pre>'; echo $value; echo '</pre>';
}
This is what my file looks like to give you an idea (So essentially how do I get the tags within [SettlementData], [0], [Fulfillment], [Item], etc. ?):
I would like to move this data into a MySQL database whose columns match the tags of the file.
Your problem is two folded.
The first part of the problem is to do the introspection on the database structure. That is, obtain all table names and obtain the column names of these. Most modern databases offer this functionality, so does MySQL. In MySQL those are the INFORMATION_SCHEMA Tables. You can query them as if those were normal database tables. I generally recommend PDO for that in PHP, mysqli is naturally doing the job perfectly as well.
The second part is parsing the XML data and mapping it's data onto the database tables (you use SimpleXMLElement for that in your question so I related to it specifically). For that you first of all need to find out how you would like to map the data from the XML onto the database. An XML file does not have a 2D structure like a relational database table, but it has a tree structure.
For example (if I read your question right) you identify Message->SettlementReport->SettlementData as the first "table". For that specific example it is easy as the <SettlementData> only has child-elements that could represent a column name (the element name) and value (the text-content). For that it is easy:
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $name => $value ) {
echo $name, ': ', $value, "\n";
}
As you can see, specifying the key assignment in the foreach clause will give you the element name with SimpleXMLElement. Alternatively, the SimpleXMLElement::getName() method does the same (just an example which does the same just with slightly different code):
header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $value) {
$name = $value->getName();
echo $name, ': ', $value, "\n";
}
In this case you benefit from the fact that the Iterator provided in the foreach of the SimpleXMLElement you access via $xml->...->SettlementData traverses all child-elements.
A more generic concept would be Xpath here. So bear with me presenting you a third example which - again - does a similar output:
header('Content-Type: text/plain; charset=utf-8');
$rows = $xml->xpath('/*/Message/SettlementReport/SettlementData');
foreach ($rows as $row) {
foreach ($row as $column) {
$name = $column->getName();
$value = (string) $column;
echo $name, ': ', $value, "\n";
}
}
However, as mentioned earlier, mapping a tree-structure (N-Depth) onto a 2D-structure (a database table) might now always be that straight forward.
If you're looking what could be an outcome (there will most often be data-loss or data-duplication) a more complex PHP example is given in a previous Q&A:
How excel reads XML file?
PHP XML to dynamic table
Please note: As the matter of fact such mappings on it's own can be complex, the questions and answers inherit from that complexity. This first of all means those might not be easy to read but also - perhaps more prominently - might just not apply to your question. Those are merely to broaden your view and provide and some examples for certain scenarios.
I hope this is helpful, please provide any feedback in form of comments below. Your problem might or might not be less problematic, so this hopefully helps you to decide how/where to go on.
I tried with SimpleXML but it skips text data. However, using the Document Object Model extension works.
This returns an array where each element is an array with 2 keys: tag and text, returned in the order in which the tree is walked.
<?php
// recursive, pass by reference (spare memory ? meh...)
// can skip non tag elements (removes lots of empty elements)
function tagData(&$node, $skipNonTag=false) {
// get function name, allows to rename function without too much work
$self = __FUNCTION__;
// init
$out = array();
$innerXML = '';
// get document
$doc = $node->nodeName == '#document'
? $node
: $node->ownerDocument;
// current tag
// we use a reference to innerXML to fill it later to keep the tree order
// without ref, this would go after the loop, children would appear first
// not really important but we never know
if(!(mb_substr($node->nodeName,0,1) == '#' && $skipNonTag)) {
$out[] = array(
'tag' => $node->nodeName,
'text' => &$innerXML,
);
}
// build current innerXML and process children
// check for children
if($node->hasChildNodes()) {
// process children
foreach($node->childNodes as $child) {
// build current innerXML
$innerXML .= $doc->saveXML($child);
// repeat process with children
$out = array_merge($out, $self($child, $skipNonTag));
}
}
// return current + children
return $out;
}
$xml = new DOMDocument();
$xml->load($target_file) or die ("Error: Cannot load xml");
$tags = tagData($xml, true);
//print_r($tags);
?>
I recently (2 weeks ago) started coding in PHP and today I ran into a problem and wondering if somebody can help/guide me.
I am getting xml data from a Web Service and want to render the data as show in below image
The fetched XML looks like this
<pricesheets>
<pricesheet>
<buyinggroupname>China</buyinggroupname>
<categoryname>Category B</categoryname>
<currency>USD</currency>
<discamt>39330.00</discamt>
<productdesc>Product B description</productdesc>
<prdouctId> Product B </productId>
</pricesheet>
<pricesheet>
<buyinggroupname>Asia</buyinggroupname>
<categoryname>Category A</categoryname>
<currency>USD</currency>
<discamt>39330.00</discamt>
<productdesc>Product A description</productdesc>
<prodouctId> Product A </productId>
</pricesheet>
</pricesheets>
The issue I am having is what's the best way to parse above XML so that I can render products based on 'buyinggroupname' and 'categoryname'. I can easily accomplish the collapse and expand feature once I know how to render the data.
Below is what I have done to achieve what I want. But I know for sure that my code is NOT efficient and scalable.
$xmldata; // XML return by the webservice
$data = simplexml_load_string($xmldata);
$category_A_items = '';
$category_B_items = '';
foreach ($data as $object) {
if($object->categoryname == 'Category A') { // Bad Idea : Hard coded category
$category_A_items .= '<tr><td>'.$object->prdouctId.'</td><td>'. $object->productdesc. '</td><td>'. $object->discamt. '</td></tr>';
}
elseif($object->CATEGORYNAME == 'Category B') { // Bad Idea : Hard coded category
$category_B_items .='<tr><td>'.$object->prdouctId. '</td><td>'. $object->productdesc. '</td><td>'. $object->discamt. '</td></tr>';
}
}
//Render Category A items in table
if(strlen($category_A_items) > 0) {
echo '<h3>CAD</h3>';
echo '<table><tr><th>Product Name</th><th>Description</th><th>Price</th></tr>';
echo $cadItems;
echo '</table>'. PHP_EOL;
}
//Render Category B items in table
if(strlen($category_B_items) > 0) {
echo '<h3>Breast Biopsy</h3>';
echo '<table><tr><th>Product Name</th><th>Description</th><th>Price</th></tr>';
echo $breastBiopsy;
echo '</table>'. PHP_EOL;
}
The above code only renders the data based on categories ( which are hard coded). Now what would be better way of doing the same so that I can render the data based on 'buyingroupname' and 'categoryname' without hard coding either of this two values in the php code.
Thanks in advance!
get an array of unique <categoryname>-nodes with xpath, then loop through it and select all <pricesheet>-nodes with that specific category, letting xpath do that job, again:
$xml = simplexml_load_string($x);
$cat = array_unique($xml->xpath("//categoryname"));
foreach ($cat as $c) {
echo "$c<br />";
foreach ($xml->xpath("//pricesheet[categoryname='$c']") as $p) {
echo $p->productId."<br />";
}
}
see a live-demo # http://codepad.viper-7.com/m9ruRU
Of course, you have to add code for creating tables...
Putting the strings in arrays with variable keys lets PHP keep them organized for you, and you don't have to know any category names at all. I used multidimensional arrays so that each buyingroup has its categories inside it. Then you loop through the arrays to make each table. Let me know if you need more explanation. I misunderstood your image the first time I saw it.
$xmldata; // XML return by the webservice
$data = simplexml_load_string($xmldata);
$buyinggroups = array();
foreach ($data as $object) {
if(isset($object->buyinggroupname) || isset($object->BUYINGGROUPNAME)) {
if(isset($object->buyinggroupname)) {
$name = $object->buyinggroupname;
} else {
$name = $object->BUYINGGROUPNAME;
}
}
if(isset($object->categoryname) || isset($object->CATEGORYNAME)) {
if(isset($object->categoryname)) {
$category = $object->categoryname;
} else {
$category = $object->CATEGORYNAME;
}
}
if(isset($category) && isset($name)) { //just making sure this row is OK
if(!isset($buyinggroups[$name])) {
$buyinggroups[$name] = array(); //initialize the outer array
}
if(!isset($buyinggroups[$name][$category])) {
$buyinggroups[$name][$category] = ''; //this is like your previous $category_A_items
}
$buyinggroups[$name][$category] .= '<tr><td>'.$object->productId.'</td><td>'. $object->productdesc. '</td><td>'. $object->discamt. '</td></tr>';
}
}
//Render all categories in lots of tables
//I am guessing at what HTML you want here; I don't think it's necessarily correct
echo '<table>'. PHP_EOL;
foreach($buyinggroups as $name=>$set) {
echo '<tr><th colspan="2">'.$name.'</th></tr>'. PHP_EOL;
echo '<tr><th> </th><td>';
foreach($set as $category=>$rows) {
echo '<table>';
echo '<tr><th><h3>'.$category.'</h3></th>'. PHP_EOL;
echo '<td><table><tr><th>Product Name</th><th>Description</th><th>Price</th></tr>';
echo $rows;
echo '</table>'. PHP_EOL;
}
echo '</td></tr>';
}
echo '</table>';
EDIT:
This can't possibly be beyond your ability to debug. You are getting everything you need in order to debug. PHP tells you the line number and the error. You google the error and find out what it means. Then you go to that line number and see how what's there corresponds to the thing you googled. In this case, I can tell you that "illegal offset type" means that you have an array key that is not a string or integer. On those lines in the error messages, you have the array keys $name and $category. Try var_dump($name) and var_dump($category) to find out what they actually are, or even var_dump($object) to find out how to get name and category out of the object.
I'm having a some trouble accessing attributes in my XML. My code is below. Initially I had two loops and this was working with no problems.
I would first get the image names and then use the second loop to get the story heading and story details. Then insert everything into the database. I want to tidy up the code and use only one loop. My image name is store in the Href attribute. ()
Sample XML layout (http://pastie.org/1850682). The XML layout is a bit messy so that was the reason for using two loops.
$xml = new SimpleXMLElement('entertainment/Showbiz.xml', null, true);
// Get story images
//$i=0;
//$image = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent/NewsComponent/NewsComponent/ContentItem');
// foreach($image as $imageNode){
// $attributeArray = $imageNode->attributes();
// if ($attributeArray != ""){
// $imageArray[$i] = $attributeArray;
// $i++;
// }
//}
// Get story header & detail
$i=0;
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent');
foreach($story as $contentItem){
//$dbImage = $imageArray[$i]['Href'];
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
$strDetail = "";
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.content/p') as $detail){
$strDetail .= '<p>'.$detail.'</p>';
foreach($contentItem->xpath('NewsComponent/NewsComponent/ContentItem') as $imageNode){
$dbImage = $imageNode->attributes();
}
}
$link = getUnique($headline);
$sql = "INSERT INTO tablename (headline, detail, image, link) VALUES ('".mysql_real_escape_string($headline)."', '".mysql_real_escape_string($strDetail)."', '".mysql_real_escape_string($dbImage)."', '".$link."')";
if (mysql_query($sql, $db) or die(mysql_error())){
echo "Loaded ";
}else{
echo "Not Loaded ";
}
}
$i++;
}
I think I'm close to getting it. I tried putting a few echo statements in the fourth nested foreach loop, but nothing was out. So its not executing that loop. I've been at this for a few hours and googled as well, just can't manage to get it.
If all else fails, I'll just go back to using two loops.
Regards,
Stephen
This was pretty difficult to follow. I've simplified the structure so we can see the parts of the hierarchy we care about.
It appears that the NewsComponent that has a Duid attribute is what defines/contains one complete news piece. Of its two children, the first child NewsComponent contains the summary and text, while the second child NewsComponent contains the image.
Your initial XPath query is for 'NewsItem/NewsComponent/NewsComponent/NewsComponent', which is the first NewsComponent child (the one with the body text). You can't find the image from that point because the image isn't within that NewsComponent; you've gone one level too deep. (I was tipped off by the fact I got a PHP Notice: Undefined variable: dbImage.) Thus, drop your initial XPath query back a level, and add that extra level to your subsequent XPath queries where needed.
From this:
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent');
foreach($story as $contentItem){
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.content/p') as $detail){
foreach($contentItem->xpath('NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}
to this:
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent');
foreach($story as $contentItem){
foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p') as $detail){
foreach($contentItem->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}
However, the image still doesn't work after that. Because you're using loops (sometimes unnecessarily), $dbImage gets reassigned to an empty string. The first ContentItem has the Href attribute, which gets assigned to $dbImage. But then it loops to the next ContentItem, which has no attributes and therefore overwrites $dbImage with an empty value. I'd recommend modifying that XPath query to find only ContentItems that have an Href attribute, like this:
->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[#Href]')
That should do it.
Other thoughts
Refactor to clean up this code, if/where possible.
As I mentioned, sometimes you are looping and nesting when you don't need to, and it just ends up being harder to follow and potentially introducing logical bugs (like the image one). It seems that the structure of this file will always be consistent. If so, you can forgo some looping and go straight for the pieces of data you're looking for. You could do something like this:
// Get story header & detail
$stories = $xml->xpath('/NewsML/NewsItem/NewsComponent/NewsComponent');
foreach ($stories as $story) {
$headlineItem = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1');
$headline = $headlineItem[0];
$detailItems = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p');
$strDetail = '<p>' . implode('</p><p>', $detailItems) . '</p>';
$imageItem = $story->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[#Href]');
$imageAtts = $imageItem[0]->attributes();
$dbImage = $imageAtts['Href'];
$link = getUnique($headline);
$sql = "INSERT INTO tablename (headline, detail, image, link) VALUES ('".mysql_real_escape_string($headline)."', '".mysql_real_escape_string($strDetail)."', '".mysql_real_escape_string($dbImage)."', '".$link."')";
if (mysql_query($sql, $db) or die(mysql_error())) {
echo "Loaded ";
} else {
echo "Not Loaded ";
}
}
This is a very basic question, so excuse my lack of knowledge.
I'm trying to output a JSON query from Freebase in PHP. I've already been able to parse the JSON into PHP using cURL and json_decode.
Here is a link to the JSON array (for some reason I can't get this to link directly):
http://www.freebase.com/api/service/mqlread?query={%20%22query%22%3A%20[{%20%22type%22%3A%20%22%2Fpeople%2Fperson%22%2C%20%22ns0%3Atype%22%3A%20%22%2Fbase%2Fbillionaires%2Fbillionaire%22%2C%20%22employment_history%22%3A%20[{%20%22company%22%3A%20null%20}]%2C%20%22name%22%3A%20null%20}]%20}
I'm able to ouput the first level of the array (Bill Gates), but not the 2nd level (Microsoft).
I've figured out how to display and loop through the people's names, just not their associated companies.
So my code, thus far, gets me a list of names.
$results = json_decode($response)->result;
foreach ($results as $name) {
echo $name->name . '<br/>';
I want the companies associated with each name to be displayed.
The browser-format should be:
Person 1 Name:
Company Name 1
Company Name 2
etc.
Person 2 Name:
Company Name 1
etc.
Thanks for any pointers--I'm sure that I'm just missing the simple way to structure the PHP code to display this easily.
How about:
$results = json_decode($response)->result;
foreach ($results as $person) {
echo $person->name . '<br/>';
foreach($person->employment_history as $employer) {
echo $employer->company . '<br/>';
}
echo '<hr />'; // horizontal rule for good measure
}