How Do i use array_push in foreach loop PHP? - php

Here is example which I have try
<?php
include 'spider/classes/simple_html_dom.php';
$html = new simple_html_dom();
$html->load("<html><body><h2>Heading 1</h2><h2>This heading 2</h2></p></p></body></html>");
$e = $html->find("h2", 0);
$key = array();
if($e->plaintext != ""){
foreach($html->find("h2", 0) as $e){
//echo $e->plaintext;
array_push($key, $e->plaintext);
}
} else {
echo "error";
}
print_r($key);
?>
Result:
Array ( [0] => [1] => [2] => [3] => [4] => [5] => Heading 1This heading 2
[6] => [7] => )
How Do i use array_push to create an array?

What happens, when you try this code?
I removed the first "find" and i also found an example on the internet, where the second param of "find" was not set.
<?php
include 'spider/classes/simple_html_dom.php';
$html = new simple_html_dom();
$html->load("<html><body><h2>Heading 1</h2><h2>This heading 2</h2></p></p></body></html>");
$key = array();
if(isset($html)){
foreach($html->find("h2") as $e){
//echo $e->plaintext;
array_push($key, $e->plaintext);
}
} else {
echo "error";
}
print_r($key);
?>
Explanation:
// Find all anchors, returns a array of element objects
$ret = $html->find('a');
// Find (N)th anchor, returns element object or null if not found (zero based)
$ret = $html->find('a', 0);

Here's an alternative with the default DOMDocument class.
$html = new DOMDocument('1.0','utf-8');
$html->loadHTML("<html><body><h2>Heading 1</h2><h2>This heading 2</h2></p></p></body></html>");
$key = array();
$h2 = $html->getElementsByTagName('h2');
for ($i = 0; $i < $h2->length; $i++) {
array_push($key, $h2->item($i)->nodeValue);
}
print_r($key);

Related

replace values of keys in json1 from Json2

I am very very new to php.. actually i am from java domain. But, i have to do some work in php for integration. My scenario is, i have one json array which will have 4 keys for ex:
one json --> {"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"}.
I will be getting another JSON which ever edited from admin panel. for example if i updated any key, only that key will coming in the
second JSON --> for ex: {"blog_heading":"def"}
Now, i have to replace the value of second json to first json. example output for above scenario like I am very very new to php.. actually i am from java domain. But, i have to do some work in php for integration. My scenario is, i have one json array which will have 4 keys for ex:
output json --> {"id":7,"active":1,"blogId":"abc","blog_heading":"def"}.
So i am trying as below,
$id = json_decode($data_string);
$id2 = json_encode($post);
$id5 = json_decode($id2);
$id6 = array();
foreach ($id as $key => $value)
{
$log->debug($key . ': ' . $value);
if (array_key_exists($key, $id5->data)) {
$log->debug($key . 'element is in the array');
$log->debug($value . 'element is in the array');
//array_push($id5, "apple", "raspberry");
$id3 = array($key => $value);
$id3[$key] = $value;
$log->debug($id3);
}else{
$log->debug($key . 'element is not in the array');
}
}
$id7 = json_encode($id2);
$log->debug($id7);
id5 data is : $id5
DEBUG - 2017-06-05T02:26:20-04:00 - stdClass Object
(
[meta] => stdClass Object
(
[table] => story
[type] => item
)
[data] => stdClass Object
(
[id] => 7
[active] => 1
[blogId] => abc
[blog_heading] => xyz
)
)
==================
Log of $id :
stdClass Object
(
[active] => 1
[blog_heading] => def
[id] => 7
)
Please suggest me how can i achieve this... Anything i am doing wrong here
Please try that:
$j1 = '{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"}';
$j2 = '{"blog_heading":"def"}';
$result = json_encode(
array_merge(
json_decode($j1, true),
json_decode($j2, true)
)
);
<?php
$json1='{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"}';
$json2='{"blog_heading":"def"}';
$json1=json_decode($json1);
$json2=json_decode($json2);
foreach ($json1 as $key => $value) {
if($json2->$key){
$json1->$key=$json2->$key;
}
}
$json1=json_encode($json1);
$json2=json_encode($json2);
If you have only one element in array,Do like this
$a = json_decode('{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"}',true);
$b = json_decode('{"blog_heading":"def"}',true);
$a['blog_heading'] = $b['blog_heading'];
print_r($a);
If you have multiple element like this :
$c = json_decode('[{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"},
{"id":8,"active":1,"blogId":"abc","blog_heading":"xyz"}]',true);
$d = json_decode('[{"blog_heading":"def"},{"blog_heading":"hello"}]',true);
$return = array();
for ($i=0; $i < count($c); $i++) {
$c[$i]['blog_heading'] = $d[$i]['blog_heading'];
$return[] = $c[$i];
}
print_r($return);
If you want to replace value by specific id
$c = json_decode('[{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"},
{"id":8,"active":1,"blogId":"abc","blog_heading":"xyz"}]',true);
$d = json_decode('[{"id":7,"blog_heading":"def"},{"id":9,"blog_heading":"hello"}]',true);
$return = array();
for ($i=0; $i < count($c); $i++) {
if($d[$i]['id'] == $c[$i]['id']) {
$c[$i]['blog_heading'] = $d[$i]['blog_heading'];
}
$return[] = $c[$i];
}
print_r($return);
Checking dynamic key value pair :
$c = json_decode('[{"id":7,"active":1,"blogId":"abc","blog_heading":"xyz"},
{"id":8,"active":1,"blogId":"abc","blog_heading":"xyz"}]',true);
$d = json_decode('[{"id":6,"blog_heading":"def"},{"id":9,"blog_heading":"hello"}]',true);
$return = array();
for ($i=0; $i < count($c); $i++) {
$result = array_intersect_key($c[$i], $d[$i]);
foreach ($result as $key => $value) {
$c[$i][$key] = $d[$i][$key];
}
$return[] = $c[$i];
}
print_r($return);
Check demo here

Array compare if value exist add value otherwise 0 in indexes

After 1st answer my output is one value missing my ratting lenght is According to Array2 not Array !,,,,,Input:
I want this output:
My output is getting 0,0,0,0
I want to compare two arrays with different length, if matches the add the value, if not then add "0" and skip after assign and go to first loop
My code:
for($i=0;$i<count($custt1);$i++){
for($j=0;$j<count($items);$j++){
if($items[$j]==$custt1[$i]){
$x[$j]=$rating[$j];
}
else{
$x[$j]=0;
}
}
for($j=0;$j<count($items1);$j++){
if($items1[$j]==$custt1[$i]){
$y[$j]=$rating1[$j];
}
else{
$y[$j]=0;
}
}
}
I want to save in x and y array if value present then add rating otherwise "0" and go to first loop but I am facing in index 0 if value not present add 0 and on 8 indexes. Hope you understand my explanation and please help me to solve this.
now my output is by applying 1st answer
<br />
<b>Notice</b>: Undefined offset: 5 in
<b>C:\xampp\htdocs\Rest\new2.php</b> on line
<b>79</b>
<br />
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
[4] => 5
[5] =>
[6] => 0
[7] => 0
[8] => 0
)
Because i am implementing recommendation system
<?php
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "hfc";
$array;
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
if ($connection) {
$sql1="SELECT item_name
from feedback
GROUP BY item_name";
$sql="SELECT customer_email_address AS customeremail,
GROUP_CONCAT(
DISTINCT CONCAT(cook_email_address,'-',item_name,'-',rating)
) AS uniqueItem
FROM feedback
GROUP BY customer_email_address";
$result = mysqli_query($connection, $sql);
while ($row = mysqli_fetch_array($result))
{
$customer_email[] = $row['customeremail'];
$cust1[]= $row['uniqueItem'].",";
}
$item[] = explode(",",$cust1[0]);
for($i=0;$i<count($item[0])-1;$i++){
$item_rating[] = explode("-",$item[0][$i]);
}
print_r ($item_rating);
for($i=0;$i<count($item_rating);$i++){
$items[]=$item_rating[$i][1];
$rating[]=$item_rating[$i][2];
}
$item1[] = explode(",",$cust1[1]);
for($i=0;$i<count($item1[0])-1;$i++){
$item_rating1[] = explode("-",$item1[0][$i]);
}
print_r ($item_rating1);
for($i=0;$i<count($item_rating1);$i++){
$items1[]=$item_rating1[$i][1];
$rating1[]=$item_rating1[$i][2];
}
$result1 = mysqli_query($connection, $sql1);
while ($row = mysqli_fetch_array($result1))
{
$custt1[]= $row['item_name'];
}
print_r ($custt1);
print_r ($items);
$output = array();
foreach ($custt1 as $i =>$item) {
if (in_array($item, $items)) {
$output[] = $rating[$i];
} else {
$output[] = 0;
}
}
print_r ($output);
for($i=0;$i<count($custt1);$i++){
for($j=0;$j<count($items);$j++){
if($items[$j]==$custt1[$i]){
$x[$i]=$rating[$j];
}
else{
$x[$i]=0;
}
}
for($j=0;$j<count($items1);$j++){
if($items1[$j]==$custt1[$i]){
$y[$j]=$rating1[$j];
}
else{
$y[$j]=0;
}
}
}
print_r ($x);
print_r ($y);
for($i1=0;$i1<count($custt1);$i1++)
{
$array[]=explode(",",$custt1[$i1]);
}
// echo count($array);
// print_r($custt1)."<br>";
/*for($i=0;$i<count($array);$i++)
{
for($y=1;$y<count($array);$y++)
{
$pearson=Corr($array[$i],$array[$y],$c=count($array));
}
}*/
$pearson=Corr($array);
echo $pearson;
}
function Corr(&$arr){
$x=$arr[0];
$y=$arr[1];
$length=count($x)-1;
$mean1=array_sum($x)/ $length;
$mean2=array_sum($y)/ $length;
echo $mean1."mean of x";
echo $mean2."mean of y";
echo "\n";
//echo $mean2;
$a=0;
$b=0;
$axb=0;
$a2=0;
$b2=0;
for($i=0;$i<$length;$i++)
{
$a=$x[$i]-$mean1;
$b=$y[$i]-$mean2;
$axb=$axb+($a*$b);
$a2=$a2+ pow($a,2);
$b2=$b2+ pow($b,2);
$corr= $axb / sqrt($a2*$b2);
}
return $corr;
}
?>
Use in_array() to tell if the element of array 1 is in array 2.
$output = array();
foreach ($array1 as $i => $item) {
if (in_array($item, $array2)) {
$output[] = $rating[$i];
} else {
$output[] = 0;
}
}

Combine arrays that have same value

I have array like this
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
if sub arrays share same value they should be be merged to one array
expected output:
$arr=[["a","b","c","f"],["d","e"]];
I`m trying to avoid doing foreach inside foreach for solving this.
It seems your inner arrays always have 2 items. so nested loops aren't necessary. Here is a solution which I originally wrote in JS but it should work just as good and most efficient in PHP:
$arr=[["a","b"],["b","c"],["d","e"],["f","c"],["h","e"]];
$output = [];
$outputKeys = [];
$counter = 0;
foreach($arr as $V) {
if(!isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
$output[$counter] = [$V[0], $V[1]];
$outputKeys[$V[0]] = &$output[$counter];
$outputKeys[$V[1]] = &$output[$counter];
$counter++;
}
elseif(isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[0]], $V[1]);
$outputKeys[$V[1]] = &$outputKeys[$V[0]];
}
elseif(!isset($outputKeys[$V[0]]) && isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[1]], $V[0]);
$outputKeys[$V[0]] = &$outputKeys[$V[1]];
}
}
var_dump($output); // [["a","b","c","f"],["d","e","h"]]
DEMO (click the execute button)
Pointers are your friends. Use them :)
The following algorithm should do what you want. It simply checks through each item and checks if it already exists in the newly created array, and if it does it adds it to that item instead of a new one:
<?php
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
$newArr = [];
foreach ($arr as $items) {
$newKey = null;
foreach ($items as $item) {
foreach ($newArr as $newItemsKey => $newItems) {
if (in_array($item, $newItems)) {
$newKey = $newItemsKey;
break 2;
}
}
}
if ($newKey !== null) {
$newArr[$newKey] = array_merge($newArr[$newKey], $items);
} else {
$newArr[] = $items;
}
}
$newArr = array_map('array_unique', $newArr);
print_r($newArr);
Output:
Array
(
[0] => Array
(
[0] => a
[1] => b
[3] => c
[4] => f
)
[1] => Array
(
[0] => d
[1] => e
)
)
DEMO
This is solution I get for now.
$arr=[["a","b","c","f"],["d","e"]];
$sortedArray = sortFunction($arr,0,array());
function sortFunction($old,$index,$new) {
if ($index == sizeof($old)) return $new;
for ($i = 0; $i<sizeof($new); $i++) {
if (count(array_intersect($new[$i],$old[$index]))) {
$new[$i] = array_unique(array_merge($old[$index],$new[$i]), SORT_REGULAR);
return sortFunction($old,$index + 1,$new);
}
}
$new[] = $old[$index];
return sortFunction($old,$index + 1,$new);
}

How can I convert a hierarchical tree to parent-child relationships?

At the moment, i'm creating a dynamic menu for my own CMS (practising) in PHP, but I don't know to save the data in my database.
Database structure:
menuitem_id
menu_id
menuitem_order
menuitem_name
menuitem_page_id
parent_menuitem_id
I do get this output as a hierarchical tree, but that isn't the desired format for storing it into my database:
Array
(
[0] => Array
(
[id] => 2
)
[1] => Array
(
[id] => 1
[children] => Array
(
[0] => Array
(
[id] => 3
[children] => Array
(
[0] => Array
(
[id] => 4
)
[1] => Array
(
[id] => 5
)
)
)
[1] => Array
(
[id] => 6
)
)
)
)
However, I want to convert this to a parent ID array with new fresh ID's (I will truncate the table and insert new data). Something like this:
Array
(
[0] => 0
[1] => 0
[2] => 2
[3] => 3
[4] => 3
[5] => 2
)
How can this be done?
Note: i have read this article, but I need the opposite code of it.
You need a recursive function:
function flattenHierarchicalArray($arr, $parentId = null) {
$items = array();
foreach ($arr as $item) {
$items[] = array('id' => $item['id'], 'parentId' = $parentId);
if (isset($item['children'])) $items = array_merge($items, flattenHierarchicalArray($item['children'], $item['id']));
}
return $items;
}
I think I have the solution combined with AlliterativeAlice's PHP code.
I'm using the Nestable plugin. That extension creates my hierarchical tree and sets it in a hidden field in my form (done by JavaScript). I updated this code to create new IDs by adding this code:
var nestable_update = function(e){
//added for updating old IDs
$(".dd-item").each(function(index){
$(this).data("id", index+1);
});
var list = e.length ? e : $(e.target),
output = list.data("output");
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable("serialize")));
} else {
output.val("JSON browser support required for this demo.");
}
};
$(".dd").nestable({
maxDepth:5
}).on("change", nestable_update);
nestable_update($(".dd").data("output", $("#nestable_output")));
I used your PHP code for getting the parentID (many thanks to AlliterativeAlice, because it's more efficient than my original PHP code):
function flatten_hierarchical_tree($arr, $parent_id=0) {
$items = array();
foreach ($arr as $item) {
$items[] = array('id' => $item['id'], 'parent_id' => $parent_id);
if (isset($item['children'])) $items = array_merge($items, flatten_hierarchical_tree($item['children'], $item['id']));
}
return $items;
}
For those who are interested in my final code. It works for storing the data in the database and build it again into a hierarchical tree + a printable tree for HTML.
JavaScript code for the nestable plugin:
var nestable_update = function(e){
$(".dd-item").each(function(index){
$(this).data("id", index+1);
});
var list = e.length ? e : $(e.target),
output = list.data("output");
if (window.JSON) {
output.val(window.JSON.stringify(list.nestable("serialize")));
} else {
output.val("JSON browser support required for this demo.");
}
};
$(".dd").nestable({
maxDepth:5
}).on("change", nestable_update);
nestable_update($(".dd").data("output", $("#nestable_output")));
Database structure:
menuitem_id
menu_id
menuitem_order
menuitem_name
menuitem_page_id
parent_menuitem_id
PHP functions for building trees (format storing data in database + format getting data from database):
function create_flatten_hierarchical_tree($tree, $parent_id=0) {
$items = array();
foreach ($tree as $item) {
$items[] = array("id" => $item["id"], "parent_id" => $parent_id);
if (isset($item["children"])) $items = array_merge($items, create_flatten_hierarchical_tree($item["children"], $item["id"]));
}
return $items;
}
function create_hierarchical_tree($tree, $root=0) {
$return = array();
foreach($tree as $child => $parent) {
if($parent["parent_menuitem_id"] == $root) {
if(isset($tree[$child]["menuitem_id"]) === true){
$parent['children'] = create_hierarchical_tree($tree, $tree[$child]["menuitem_id"]);
}
unset($tree[$child]);
$return[] = $parent;
}
}
return empty($return) ? null : $return;
}
function print_hierarchical_tree($tree, $rows_pages) {
if(!is_null($tree) && count($tree) > 0) {
$return .= "<ol class='dd-list'>";
foreach($tree as $item){
$options = "";
foreach($rows_pages as $row_pages){
$selected = "";
if($row_pages["page_id"] == $item["menuitem_page_id"]){
$selected = "selected";
}
$options .= "<option value='".$row_pages["page_id"]."' $selected>".$row_pages["friendly_url"]."</option>";
}
$return .= "<li class='dd-item' data-id='".$item["menuitem_id"]."'><div class='dd-handle'>drag</div><div class='item_wrapper'><div class='item'><div class='item_title'>".$item["menuitem_name"]."</div></div><div class='item_sub'><div class='label_input'><label for='menuitem_name".$item["menuitem_id"]."'>Menuitem name</label><input type='text' id='menuitem_name".$item["menuitem_id"]."' name='menuitem_name[]' value='".$item["menuitem_name"]."' /></div><div class='label_input'><label for='page_link".$item["menuitem_id"]."'>Page link</label><label class='select'><select id='page_link".$item["menuitem_id"]."' name='menuitem_page_id[]'>".$options."</select></label></div> <a onClick='delete_menuitem(".$item["menuitem_id"].");' class='button red_bg delete'>Delete</a></div></div>";
$return .= print_hierarchical_tree($item["children"], $rows_pages);
$return .= "</li>";
}
$return .= "</ol>";
}
return empty($return) ? null : $return;
}
Core code of menu_edit.php page:
<?php
$stmt_menuitems = $dbh->prepare("SELECT * FROM inno_mw_thurs_menuitems mi WHERE mi.menu_id=:menu_id");
$stmt_menuitems->bindParam(":menu_id", $_GET["menu_id"]);
$stmt_menuitems->execute();
if (!empty($stmt_menuitems->rowCount())) {
?>
<div class="dd">
<?php
$result = $stmt_menuitems->fetchAll();
$tree = create_hierarchical_tree($result);
$stmt_pages = $dbh->prepare("SELECT * FROM inno_mw_thurs_pages");
$stmt_pages->execute();
$rows_pages = $stmt_pages->fetchAll();
$tree = print_hierarchical_tree($tree, $rows_pages);
echo $tree;
?>
</div>
<?php
}
Core code of menu_edit_process.php page:
if(isset($_POST["menu_id"])){
$menu_id = $_POST["menu_id"];
$nestable_output = json_decode($_POST["nestable_output"], true);
$parent_menuitem_ids_arr = create_flatten_hierarchical_tree($nestable_output);
$stmt = $dbh->prepare("TRUNCATE TABLE inno_mw_thurs_menuitems");
$stmt->execute();
$stmt = $dbh->prepare("INSERT INTO inno_mw_thurs_menuitems (menu_id, menuitem_order, menuitem_name, menuitem_page_id, parent_menuitem_id) VALUES (:menu_id, :menuitem_order, :menuitem_name, :menuitem_page_id, :parent_menuitem_id)");
$menuitem_order_arr = array();
foreach($_POST["menuitem_name"] as $f => $name){
$menuitem_name = $_POST["menuitem_name"][$f];
$menuitem_page_id = $_POST["menuitem_page_id"][$f];
$parent_menuitem_id = $parent_menuitem_ids_arr[$f]["parent_id"];
if(array_key_exists($parent_menuitem_id, $menuitem_order_arr) && $parent_menuitem_id != 0){
$menuitem_order_arr[$parent_menuitem_id] += 1;
}
else{
$menuitem_order_arr[$parent_menuitem_id] = 0;
}
$stmt->bindParam(":menu_id", $menu_id);
$stmt->bindParam(":menuitem_order", $menuitem_order_arr[$parent_menuitem_id]);
$stmt->bindParam(":menuitem_name", $menuitem_name);
$stmt->bindParam(":menuitem_page_id", $menuitem_page_id);
$stmt->bindParam(":parent_menuitem_id", $parent_menuitem_id);
$stmt->execute();
}
header("location: menus_list.php");
}
Please, feel free to improve this code.

Foreach loop in function only returns last item in array

I am having trouble with my php code below. I am trying to have the function below to return the UPC and imageURL for each item. When I print_r the result after the loop I receive this.
Array
(
[upc] => 043396066731
[ImageURL] => http://ecx.images-amazon.com/images/I/51HKXNNT53L._SL200_.jpg
)
Array
(
[upc] => 096009394097
[ImageURL] => http://ecx.images-amazon.com/images/I/512NKNWC8EL._SL200_.jpg
)
However, when I use return result and then print_r I only receive the last response. Why is this and how can I fix my code to receive the values from both items? I have searched Google and other Stackoverflow questions and can find similar situations, but I am still struggling.
Array
(
[upc] => 096009394097
[ImageURL] => http://ecx.images-amazon.com/images/I/512NKNWC8EL._SL200_.jpg
)
Here is my function
function invokeGetMatchingProductForId(MarketplaceWebServiceProducts_Interface $service, $request)
{
// try {
$response = $service->getMatchingProductForId($request);
$dom = new DOMDocument();
$dom->loadXML($response->toXML());
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$parsed_xml = simplexml_import_dom($dom);
//print_r($parsed_xml);
$Result = array();
foreach($parsed_xml->GetMatchingProductForIdResult as $item )
{
$status = $item->attributes()->status;
if (stristr($status, "Success") == true)
{
$Result['upc'] = (string)$item->attributes()->Id;
$Result['ImageURL'] = str_replace('SL75','SL200',$item->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->SmallImage->URL);
} else {
$Result['upc'] = (string)$item->attributes()->Id;
$Result['ImageURL'] = "";
}
}
print_r($Result);
}
// return $Result;
// }
// $amazonResult =invokeGetMatchingProductForId($service, $request);
// print_r($amazonResult);
You need to assign second key for your array:
$Result['upc'][] = ;
$Result['ImageURL'][] = ;
^-----
Currently you are resetting this $Result['upc'] every time you assign new value.
according to your requirement you need to create two dimensional array
use foreach like this
foreach($parsed_xml->GetMatchingProductForIdResult as $item )
{
$status = $item->attributes()->status;
if (stristr($status, "Success") == true)
{
$Result[]['upc'] = (string)$item->attributes()->Id;
$Result[]['ImageURL'] = str_replace('SL75','SL200',$item->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->SmallImage->URL);
}
else
{
$Result[]['upc'] = (string)$item->attributes()->Id;
$Result[]['ImageURL'] = "";
}
}
print_r($Result);

Categories