I am quite new to php. I am experiencing problems with nested foreach loops. It seems I cannot read the data in $row, eg. $row['Tournament_NB_ID1']
I have tried looping through $arr_tournaments with a while loop before the foreach loops and there is data in the array. Also, I have tried changing the php version of the server, nothing seems to help. The code...
include 'variable.php';
include 'db_connect.php';
//Connect to database
db_connect();
$arr_tournaments = mysqli_query($GLOBALS['db_con'], "SELECT * FROM tournaments");
echo 'Current PHP version: ' . phpversion() . '<br>';
print_r ($arr_tournaments);
//$xml = simplexml_load_file("football.xml");
$xml = simplexml_load_file($xml_nordicbet_football); //Live file
foreach ($xml->children() as $game) {
foreach ($arr_tournaments as $row) {
if ($game->BreadCrumbs == $row['Tournament_NB_ID1']) {
$id = $game['id'];
$type = '1X2'; //Type of bet
$season = $game->Season;
$breadcrumbs = $game->Game->BreadCrumbs;
$gamestarttime = $game->GameStartTime;
echo 'Loop1';
foreach ($game->OutcomeSet as $outcomeset) {
if ($outcomeset['type'] == $row['Tournament_NB_ID2']) {
echo 'loop2';
$outcomeset_type = $outcomeset['type'];
echo $outcomeset_type;
foreach ($outcomeset->Outcome as $outcome) {
switch ($outcome['name']) {
case '1':
$outcome_odds1 = $outcome['odds'];
$outcome_p1 = utf8_decode($outcome->Participant); //utf8_decode converts to iso ISO-8859-1 (has æøå)
case 'X':
$outcome_oddsX = $outcome['odds'];
case '2':
$outcome_odds2 = $outcome['odds'];
$outcome_p2 = utf8_decode($outcome->Participant);
}
}
}
}
$sql = "INSERT INTO ogames (Game_NB_ID, Participant1, Participant2, TournamentID, Odds_1, Odds_X, Odds_2, StartDateTime, GameType)
VALUES
('$id', '$outcome_p1', '$outcome_p2', '$row[TournamentID]', '$outcome_odds1', '$outcome_oddsX', '$outcome_odds2', '$gamestarttime', '$type')
ON DUPLICATE KEY UPDATE
Odds_1 = $outcome_odds1, Odds_X = $outcome_oddsX, Odds_2 = $outcome_odds2";
// Does not update start time!!
if (!mysqli_query($db_con, $sql)) {
die('Error: ' . mysqli_error($db_con));
}
echo "1 record added" . "<br>";
}
}
}
mysqli_close($db_con);
Related
I was not having any luck with searching so if this is a duplicate please let me know rather than downvoting.
I have a script for a game server that fills a database with the character data (name, level, userid and character type).
Rather than deleting the whole sql table each time and recreating it, I have it perform a check on the character data in the table and compare and only update whats different. it all works nicely.
However, A certain few character names are causing issues.
[09-Sep-2017 02:16:34 America/New_York] PHP Notice: Undefined index: 1OO4 in C:\Scripts\charlist.php on line 56
[09-Sep-2017 02:16:34 America/New_York] PHP Notice: Undefined index: 1zxx in C:\Scripts\charlist.php on line 56
That is this part of the script:
if ($current[$charName] !== $level) {
Where $current is an array of all the characters already in the database, I have it populate the array as Name => Level
The characters are in the database but they are not updating due to the error its throwing (as seen above) I tried wrapping $charName in "" but it did not work.
If anyone can provide advice it would be greatly appreciated.
entire script for reference, can see where i've fixed it in here.
<?php
$ClanServer = "";
$SodServer = '';
$UID = "";
$PWD = "";
$file = 'C:\account.txt';
$errlog = ini_get('php_errors');
$ConnInfo = array("UID"=>"$UID", "PWD"=>"$PWD", "CharacterSet" => "UTF-8");
$ClanConn = sqlsrv_connect($ClanServer, $ConnInfo);
$SodConn = sqlsrv_connect($SodServer, $ConnInfo);
if (!$SodConn) {
die('Connection Failed!');
} else {
echo "Connection Successful!<br />".PHP_EOL;
$query = "SELECT * FROM soddb.dbo.levellist";
$result = sqlsrv_query($SodConn, $query, array(), array('Scrollable' => 'buffered'));
$current = array();
$files = array();
while ($row = sqlsrv_fetch_array($result)) {
$name = $row['CharName'];
$current["'".$name."'"] = $row['CharLevel'];
}
$rootDir = realpath('C:/PT-Server/DataServer/userdata/');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootDir), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
if (substr($name, -4) == '.dat') {
$fOpen = fopen($name, "r");
$fRead = fread($fOpen,filesize($name));
/* details */
$charLevel = substr($fRead,0xc8,1);
$charClass = substr($fRead,0xc4,1);
$charName = trim(substr($fRead,0x10,16),"\x00");
$charID = trim(substr($fRead,0x2d0,16),"\x00");
$level = ord($charLevel);
#fclose($fOpen);
$files[] = $charName;
if ($charName == "")
{
unlink($name); // Delete char file with no name...
}
switch (ord($charClass)){
case 1: $class = 'Fighter'; break;
case 2: $class = 'Mechanician'; break;
case 3: $class = 'Archer'; break;
case 4: $class = 'Pikeman'; break;
case 5: $class = 'Atalanta'; break;
case 6: $class = 'Knight'; break;
case 7: $class = 'Magician'; break;
case 8: $class = 'Priestess'; break;
case 9: $class = 'Assassin'; break;
case 10: $class = 'Shaman'; break;
}
if (in_array("'".$charName."'",array_keys($current))) {
if ($current["'".$charName."'"] !== $level) {
$dbentry = "UPDATE soddb.dbo.levellist SET CharLevel='$level',CharClass='$class' WHERE CharName='$charName'";
$clanupdate = "UPDATE clandb.dbo.ul SET ChLv='$level' WHERE ChName='$charName'";
$enter = sqlsrv_query($SodConn, $dbentry);
sqlsrv_query($ClanConn, $clanupdate);
if ($enter) {
echo "Update $charName, $level successful!<br />".PHP_EOL;
}
}
} else {
$dbentry = "INSERT INTO soddb.dbo.Levellist ([ID], [CharName], [CharClass], [CharLevel]) VALUES ('$charID', '$charName', '$class', '$level') ";
$clanupdate = "UPDATE clandb.dbo.ul SET ChLv='$level' WHERE ChName='$charName'";
$enter = sqlsrv_query($SodConn, $dbentry);
sqlsrv_query($ClanConn, $clanupdate);
if ($enter) {
echo "Insert $charName, $level successful!<br />".PHP_EOL;
}
}
}
}
/* Remove deleted characters */
foreach ($current as $k => $v) {
if (!in_array($k, $files)) {
$query = "DELETE FROM soddb.dbo.levellist WHERE CharName='$k'";
sqlsrv_query($SodConn, $query);
}
}
sqlsrv_close($ClanConn);
sqlsrv_close($SodConn);
}
?>
I've worked it out,
where I push the names to the array ($current[$name] = $level;)
I encapsulated that with '' which treats its as a string number a number (where the name was starting with a number)
so its now $current["'".$name."'"] = $level; and i did the same further down
if (in_array("'".$charName."'",array_keys($current))) {
if ($current["'".$charName."'"] !== $level) {
do stuff
}
}
I've now run the script about 15 times to test and its not giving the issue at all.
I have a php which will include my datas inside my database.
But in my page I have a div which can be replicated, so I send this informations into an array (imploded with a "#!#" to avoid any kind of wrong explode when I insert it on my database).
My problem is that if the user doesn't insert anything on the first div content fields I shall not do the insert, and it still does.
if ($_GET['action_ent'] != "#!##!##!#")
{
$myInputs = $_GET['action_ent'];
foreach ($myInputs as $eachInput)
{
$valores = $eachInput;
print_r($valores);
$dummy = explode('#!#', $valores);
$acao = $dummy[0];
$resp_acao = $dummy[1];
$inic_plan_acao = $dummy[2];
$fim_plan_acao = $dummy[3];
$inicio_acc = explode("/", $inic_plan_acao);
$fim_acc = explode("/", $fim_plan_acao);
$inicio_action = $inicio_acc[2]."-".$inicio_acc[1]."-".$inicio_acc[0];
$fim_action = $fim_acc[2]."-".$fim_acc[1]."-".$fim_acc[0];
$result2 = mysql_query("INSERT INTO `demv3`.`entraves_action` (`action_id`, `ent_id`, `resp_ent`, `data_fim`,`action_desc`,`action_resp`,`action_comeco`,`action_fim`) VALUES ('0', '$ent_id', '$resp_ent', '$data_fim', '$acao', '$resp_acao', '$inicio_action', '$fim_action')");
}
}
else
{
echo "NOTHING";
}
Try checking the first item in the foreach:
if ($_GET['action_ent'] != "#!##!##!#")
{
$myInputs = $_GET['action_ent'];
foreach ($myInputs as $eachInput)
{
if(empty($eachInput)) {
echo 'NOTHING';
break;
}
$valores = $eachInput;
print_r($valores);
$dummy = explode('#!#', $valores);
$acao = $dummy[0];
$resp_acao = $dummy[1];
$inic_plan_acao = $dummy[2];
$fim_plan_acao = $dummy[3];
$inicio_acc = explode("/", $inic_plan_acao);
$fim_acc = explode("/", $fim_plan_acao);
$inicio_action = $inicio_acc[2]."-".$inicio_acc[1]."-".$inicio_acc[0];
$fim_action = $fim_acc[2]."-".$fim_acc[1]."-".$fim_acc[0];
$result2 = mysql_query("INSERT INTO `demv3`.`entraves_action` (`action_id`, `ent_id`, `resp_ent`, `data_fim`,`action_desc`,`action_resp`,`action_comeco`,`action_fim`) VALUES ('0', '$ent_id', '$resp_ent', '$data_fim', '$acao', '$resp_acao', '$inicio_action', '$fim_action')");
}
}
else
{
echo "NOTHING";
}
Just be aware that if any other input besides the first one is empty it will break the loop. In order to avoid major changes in your logic you can resolve this with a counter or a boolean flag:
if(empty($eachInput) && $counter == 0) {
echo 'NOTHING';
break;
}
I've a problem with a MySQL script. The script should echo every element out of the table where "gruppe" is $gruppe. But I am only getting one single output.
<?php
if ( $_SERVER["REQUEST_METHOD"] == 'POST' ) {
$gruppe = $_POST["gruppe"];
$mail = $_POST["mail"];
$betreff = $_POST["betreff"];
$nachricht = $_POST["nachricht"];
if (!empty($nachricht)) {
$sql = new rex_sql;
$sql->debugsql = 0; //Ausgabe Query
$sql->setQuery("SELECT * FROM $db_users WHERE gruppe = '$gruppe'");
for($i=0;$i<$sql->getRows();$i++)
{
$id_mail = $sql->getValue("id");
$mail_mail = $sql->getValue("email");
$ausgabe_mail = $mail_mail;
$sql->next();
}
}
}
?>
<?php echo $ausgabe_mail ?>
Your echo-statement is outside the loop. The loop fetches all email addresses, one by one, and stores them in $mail_mail and $ausgabe_mail. Each iteration of the loop overwrites the previous contents of both variables.
After the loop ends, you echo the last value of $ausgabe_email.
Retry with the echo inside the loop:
<?php
if ( $_SERVER["REQUEST_METHOD"] == 'POST' ) {
$gruppe = $_POST["gruppe"];
$mail = $_POST["mail"];
$betreff = $_POST["betreff"];
$nachricht = $_POST["nachricht"];
if (!empty($nachricht)) {
$sql = new rex_sql;
$sql->debugsql = 0; //Ausgabe Query
$sql->setQuery("SELECT * FROM $db_users WHERE gruppe = '$gruppe'");
for($i=0;$i<$sql->getRows();$i++) {
$id_mail = $sql->getValue("id");
$mail_mail = $sql->getValue("email");
$ausgabe_mail .= ',' . $mail_mail;
$sql->next();
}
echo $ausgabe_mail;
}
}
?>
EDIT: as clarified, expanded the example with string concatenation and moved the echo outside the loop again.
Problem:
I am trying to delete all sublevels of a category by using a class. Currently I can only make it delete two sublevels, not three.
The database table:
CREATE TABLE betyg_category (
CID int(11) NOT NULL AUTO_INCREMENT,
Item varchar(100) NOT NULL,
Parent int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (CID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The PHP class:
<?php
class ItemTree
{
var $itemlist = array();
function ItemTree($query)
{
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
while ($row = mysql_fetch_assoc($result))
{
$this->itemlist[$row['CID']] = array(
'name' => $row['Name'],
'parent' => $row['Parent']
);
}
}
function get_tree($parent, $with_parent=0)
{
$item_tree = array();
if ($with_parent == 1 && $parent != 0)
{
$item_tree[$parent]['name'] = $this->itemlist[$parent]['name'];
$item_tree[$parent]['parent'] = $this->itemlist[$parent]['parent'];
$item_tree[$parent]['child'] = $this->get_tree($parent);
return $item_tree;
}
foreach ($this->itemlist as $key => $val)
{
if ($val['parent'] == $parent)
{
$item_tree[$key]['name'] = $val['name'];
$item_tree[$key]['parent'] = $val['parent'];
$item_tree[$key]['child'] = $this->get_tree($key);
}
}
return $item_tree;
}
function make_optionlist ($id, $class='', $delimiter='/')
{
$option_list = '';
$item_tree = $this->get_tree(0);
$options = $this->make_options($item_tree, '', $delimiter);
if (!is_array($id))
{
$id = array($id);
}
foreach($options as $row)
{
list($index, $text) = $row;
$selected = in_array($index, $id) ? ' selected="selected"' : '';
$option_list .= "<option value=\"$index\" class=\"$class\"$selected>$text</option>\n";
}
return $option_list;
}
function make_options ($item_tree, $before, $delimiter='/')
{
$before .= empty($before) ? '' : $delimiter;
$options = array();
foreach ($item_tree as $key => $val)
{
$options[] = array($key, '- '.$before.$val['name']);
if (!empty($val['child'])) {
$options = array_merge($options, $this->make_options($val['child'], $before.$val['name'], $delimiter));
}
}
return $options;
}
function get_navlinks ($navid, $tpl, $startlink='', $delimiter=' » ')
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$navlink = array();
while (isset($this->itemlist[$navid]))
{
$replace = array($navid, $this->itemlist[$navid]['name']);
$navlink[] = str_replace($search, $replace, $tpl);
$navid = $this->itemlist[$navid]['parent'];
}
if (!empty($startlink))
{
$navlink[] = str_replace($search, array(0, $startlink), $tpl);
}
$navlink = array_reverse($navlink);
return implode($delimiter, $navlink);
}
function show_tree ($parent=0, $tpl='%s', $ul_class='', $li_class='')
{
$item_tree = $this->get_tree($parent);
return $this->get_node($item_tree, $parent, $tpl, $ul_class, $li_class);
}
function get_node ($item_tree, $parent, $tpl, $ul_class, $li_class)
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$output = "\n<ul class=\"$ul_class\">\n";
foreach ($item_tree as $id => $item)
{
$replace = array($id, $item['name']);
$output .= "<li class=\"$li_class\">".str_replace($search, $replace, $tpl);
$output .= !empty($item['child']) ? "<br />".$this->get_node ($item['child'], $id, $tpl, $ul_class, $li_class) : '';
$output .= "</li>\n";
}
return $output . "</ul>\n";
}
function get_id_in_node ($id)
{
$id_list = array($id);
if (isset($this->itemlist[$id]))
{
foreach ($this->itemlist as $key => $row)
{
if ($row['parent'] == $id)
{
if (!empty($row['child']))
{
$id_list = array_merge($id_list, get_id_in_node($key));
} else
{
$id_list[] = $key;
}
}
}
}
return $id_list;
}
function get_parent ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['parent'] : false;
}
function get_item_name ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['name'] : false;
}
}
?>
Scenario:
Say you have the following structure in a :
Literature
-- Integration of sources
---- Test 1
It will result in the following in the database table:
When I try to delete this sublevel, it will leave the last sublevel in the database while it should delete it. The result will be:
The PHP code:
//Check if delete button is set
if (isset($_POST['submit-deletecategory']))
{
//Get $_POST variables for category id
$CategoryParent = intval($_POST['CategoryList']);
//Check if category is selected
if ($CategoryParent != "#")
{
//Get parent category and subsequent child categories
$query = "SELECT CID, Item AS Name, Parent FROM " . TB_CATEGORY . " ORDER BY Name";
$items = new ItemTree($query);
if ($items->get_item_name($_POST['CategoryList']) !== false)
{
//Build up erase list
$CategoryErase = $items->get_id_in_node($CategoryParent);
$CategoryEraseList = implode(", ", $CategoryErase);
}
else
{
$CategoryEraseList = 0;
}
//Remove categories from database
$query = "DELETE FROM " . TB_CATEGORY . " WHERE CID IN ($CategoryEraseList)";
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
//Return a confirmation notice
header("Location: settings.php");
exit;
}
}
Thank you in advance for any guidance I can get to solve the issue.
Here is a way to do it : use a recursive function, which will first look for the leaf item (the deepest in your tree). You remove children first, then the parent. And for each child, you remove child's children first, etc...
deleteSub(1);
function deleteSub($cat_id) {
$request = "SELECT * FROM ". TB_CATEGORY ." WHERE Parent = ".$cat_id;
$results = mysql_query($request);
while($child = mysql_fetch_array($results))
{
deleteSub($child["CID"]);
}
$request = "DELETE FROM ". TB_CATEGORY ." WHERE CID = ".$cat_id;
return mysql_query($request);
}
A better way could be use this kind of recursive function to store CIDs in an array, then make a single DELETE request, but I think you'll be able to adapt this code.
I'm not going to read or try to understand the entire code, but it seems to me you need some sort of recursion function. What I basicly would do is create a function that goes up in the hierachy and one that goes down.
Note: It has been a while since i've written anything in procedural mysql, so please check if the mysql_num_rows(),mysql_fetch_array and so on is written in the correct manner
EDIT: I've just noticed you only wanted a downwards deletion and therefore zessx's answer is more valid
<?php
function recursiveParent($id) {
$sql = 'SELECT parent FROM betyg_category WHERE CID=' . $id;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveParent($r['parent']);
}
}
$sql = 'DELETE FROM betyg_category WHERE CID=' . $id;
mysql_query($sql);
}
function recursiveChild($parent) {
$sql = 'SELECT CID FROM betyg_category WHERE parent=' . $parent;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveChild($r['CID']);
}
}
$sql = 'DELETE FROM betyg_category WHERE parent=' . $parent;
mysql_query($sql);
}
function delete($id) {
recursiveParent($id);
recursiveChild($id);
}
?>
This is my way to do. instead of recursive the query to run, i get all the child's id first then only run query. here the code refer:-
First, defined a variable called $delete_node_list as array. (to store all node id that need to be delete)
function delete_child_nodes($node_id)
{
$childs_node = $this->edirectory_model->get_child_nodes($node_id);
if(!empty($childs_node))
{
foreach($childs_node as $node)
{
$this->delete_child_nodes($node['id']);
}
}
$this->delete_node_list[] = $node_id;
}
in mysql..
$sql = 'DELETE FROM betyg_category WHERE CID IN '.$this->delete_node_list;
mysql_query($sql);
I have asked a couple of questions on here in a rush, and I am getting nowhere fast, I keep changing things and just ending up with a different problem, and no closer to having a clue what is causing it. I am a PHP MYSQL man, and I am having to work with Access via the COM class.
Basically the client has multiple servers, each with an access database, and each with a CMS, the tables should contain the same data and have slipped out of Sync. It is my job to come up with a way of resyncing them.
I have came to bringing the data out into an Array, serializing it and saving it to a file on the main server (the one all should sync to) and then on the other servers, downloading the file, unserializing it and item by item, checking if it is in the DB, and if not inserting it. The insert is failing. I have tried building an sql query for each item and doing $this->conn->Execute(); and that is failing row by row on silly things, so I am now trying this:
function syncCMS()
{
$this->output['msg'] .= "<p><b>The following properties were added to the database on ." . $this->hsite . "</b></p>";
$this->get_field_names();
$this->make_connection(); //assigns connection to $this->conn
$rs = new COM('ADODB.Recordset');
$rs->CursorType = 2;
$rs->CursorLocation = 1;
$rs->LockType = 4;
$rs->Open($this->table_name,$this->conn);
foreach ($this->awayPropertyDetails as $key => $property)
{
$this->check_for_property($property['pname']);
if (!$this->property_exists || $this->mode == "fullSync")
{
unset($values);
$bfields = array("pshow","rent","best", "oda1", "oda2", "oda3", "oda4", "oda5", "oda6", "odap", "topool","tomountain","tofitness","tosauna"); //stores the yes/no values
$q = "INSERT INTO " . $this->table_name . " (" . $this->dbfields . ") VALUES (";
foreach ($property as $k => $value)
{
if ($k == "Kimlik") {
$value = null;
}
if ($k == "tarih")
{
$value = date("d/m/Y");
$value = "'" . $value . "'";
}
if (in_array($k,$bfields))
{
if ($value == "")
{
$value = 'FALSE';
}
else
{
$value = 'TRUE';
}
}
$rs->fields->$k = $value;
$this->output['msg'] .= $property['pname'] . " added";
}
$rs->BatchUpdate();
$rs->Close();
$this->conn->Close();
//$this->download_images($property['OBJECT_NR'],$k);
//$this->output['msg'] .= "<p>Images added</p>";
}
}
$message .= "</ul>";
$this->output['msg'] .= $message;
$this->sendOutput();
//print_r($property);*/
}
And getting this:
Fatal error: Uncaught exception 'com_exception' with message 'Unable to lookup `Kimlik': Unknown name. ' in D:\inetpub...
Kimlik is the name of the first field, the Auto Number field, I took it out and the problem shifted to the second field.
I got there with:
$sql = "SELECT * FROM " . $this->table_name;
if (!$this->property_exists || $this->mode == "fullSync")
{
$this->make_connection();
$rs->Open($sql,$this->conn);
$rs->addnew();
foreach($rs->Fields as $field)
{
if ($field->name != "Kimlik")
{
$rs->Fields[$field->name] = $property[$field->name];
}
}
$rs->Update();
$rs->Close();
$this->conn->Close();
$msg = $this->download_images($property['OBJECT_NR'],$k);
$this->output['msg'] .= $property['pname'] . " added<br/>" . $msg . "<br/><br/>";
}