escaping numbers in array index in php - php

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.

Related

Prevent insert query with php

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;
}

Minimize efforts with foreach

I'm trying to build a script that will download users from a db table and attach a new random IP to each user based on his state.
The problem is that I wrote a lot of code and there is still much Copy/Paste job to be done if I keep it with this approach.
Can someone point me to the right direction on how to properly do that?
So first I have 50 of these:
$California_Text = file_get_contents('state/California.txt');
$California_textArray = explode("\n", $California_Text);
$Idaho_Text = file_get_contents('state/Idaho.txt');
$Idaho_textArray = explode("\n", $Idaho_Text);
$Illinois_Text = file_get_contents('state/Illinois.txt');
$Illinois_textArray = explode("\n", $Illinois_Text);
$Indiana_Text = file_get_contents('state/Illinois.txt');
$Indiana_textArray = explode("\n", $Indiana_Text);
$Iowa_Text = file_get_contents('state/Iowa.txt');
Then I have 50 of these:
while($row = $result->fetch_assoc()) {
if (isset($row["state"])) {
foreach ($row as $value){
$California_randArrayIndexNum = array_rand($California_textArray);
$p_California = $California_textArray[$California_randArrayIndexNum];
$Texas_randArrayIndexNum = array_rand($Texas_textArray);
$p_Texas = $Texas_textArray[$Texas_randArrayIndexNum];
$Alabama_randArrayIndexNum = array_rand($Alabama_textArray);
$p_Alabama = $Alabama_textArray[$Alabama_randArrayIndexNum];
$Alaska_randArrayIndexNum = array_rand($Alaska_textArray);
$p_Alaska = $Texas_textArray[$Alaska_randArrayIndexNum];
$Arizona_randArrayIndexNum = array_rand($Arizona_textArray);
$p_Arizona = $California_textArray[$Arizona_randArrayIndexNum];
.....
Then I have 50 of these:
if ($row["state"] == "california") {
$stateip = $p_California;
}
else if ($row["state"] == "texas") {
$stateip = $p_Texas;
}
else if ($row["state"] == "alabama") {
$stateip = $p_Alabama;
}
else if ($row["state"] == "alaska") {
$stateip = $p_Alaska;
}
I'm pretty much sure that it's a bad approach.. Maybe there's a way to do all this with like 3 lines of foreach?
Something like this:
// holds your content
$state_content = [];
while($row = $result->fetch_assoc()) {
// check do we have state set
if (!empty($row["state"])) {
$stateip = getStateIpByName($row["state"]);
}
}
/**
* Returns random IP
*/
function getStateIpByName($state_name) {
$content = getStateContent($state_name);
return $content[array_rand($content)];
}
/**
* Returns your's state content by state name
*/
function getStateContent($state_name) {
// checks do we already have content for this state
if(!isset($state_content[$state_name])) {
// generate file name
$file_name = "state/";
$file_name .= str_replace(" ", "", ucwords($state_name));
$file_name .= ".txt";
$state_text = file_get_contents($file_name);
$state_content[$state_name] = explode("\n", $state_text);
}
return $state_content[$state_name];
}
There are probably some errors but you will get idea.
Store all states in an array and do all operations within a foreach block
$states=['california',..];
foreach($states as $state){
//Your code for one state
//Replace state name with $state variable
}

Vicidial PHP/Json/Mysql combination to pull data in monitor

The question title can be very vague but I didnt know what exactly to write so lets get to the point
I have a script that pull data from a Vicidial database to display it TV screen
Now it basically works well when there is only one Server involved cause it has only one Extension to handle, but the thing gets more complicated when there are two extensions. Better I show you the code :
$start_time = time();
$data = array();
$sql = "SELECT
extension,
vicidial_live_agents.user,
conf_exten,
vicidial_live_agents.status,
vicidial_live_agents.server_ip,
UNIX_TIMESTAMP(last_call_time) as last_call_time,
UNIX_TIMESTAMP(last_call_finish) as last_call_finish,
call_server_ip,
vicidial_live_agents.campaign_id,
vicidial_users.user_group,
vicidial_users.full_name,
vicidial_live_agents.comments,
vicidial_live_agents.calls_today,
vicidial_live_agents.callerid,
lead_id,
UNIX_TIMESTAMP(last_state_change) as last_state_change,
on_hook_agent,
ring_callerid,
agent_log_id
FROM
vicidial_live_agents,
vicidial_users
WHERE
vicidial_live_agents.user = vicidial_users.user";
$db = new mysqli("192.168.X.X", "cron", "XXXXXX", "asterisk");
$result = $db->query($sql);
$sql2 = "select callerid,lead_id,phone_number from vicidial_auto_calls";
$cidresult = $db->query($sql2);
$callerids = '';
while ($row = $cidresult->fetch_assoc()){
$callerids .= $row['callerid'] . "|";
}
while ($row = $result->fetch_assoc()){
$status = $row['status'];
if ($row['on_hook_agent'] == 'Y')
$status = 'RING';
// 3-way Check
if ($row['lead_id'] != 0){
$sql = "SELECT UNIX_TIMESTAMP(last_call_time) FROM vicidial_live_agents WHERE lead_id = '" . $db->escape_string($row['lead_id']) . "' AND status = 'INCALL' ORDER BY UNIX_TIMESTAMP(last_call_time) DESC";
$r2 = $db->query($sql);
if (!$r2){
printf("Error: %s\n", $db->error);
} else {
if ($r2->num_rows > 1){
$status = "3-WAY";
}
}
}
$epoch_sec = 0;
if (preg_match("/READY|PAUSED/i", $row['status'])){
$epoch_sec = $row['last_state_change'];
if ($row['lead_id'] > 0){
$status = 'DISPO';
}
} else {
$epoch_sec = $row['last_call_time'];
}
if (preg_match("/INCALL/i", $status)){
$sql4 = "SELECT UNIX_TIMESTAMP(parked_time) AS pt FROM parked_channels WHERE channel_group = '" . $db->escape_string($row['callerid']) . "'";
$q4 = $db->query($sql4);
if ($q4->num_rows > 0){
$status = 'PARK';
$rowP = $q4->fetch_assoc();
$epoch_sec = $rowP['pt'];
} else{
if (!preg_match("/" . $row['callerid'] . "\|/",$callerids)){
$epoch_sec = $row['last_state_change'];
$status = 'DEAD';
}
}
}
switch($status){
case 'DISPO':
$colour = '8e44ad';
break;
case 'QUEUE':
$colour = '9b59b6';
break;
case 'INCALL':
$colour = '3498db';
break;
case 'PARK':
$colour = 'e67e22';
break;
case 'DEAD':
$colour = '004D86';
$status = 'GONE';
break;
case '3-WAY':
$colour = '1abc9c';
break;
case 'RING':
$colour = '16a085';
break;
case 'PAUSED':
$colour = 'c0392b';
break;
case 'CLOSER':
$status = 'READY (C)';
case 'READY':
$colour = '27ae60';
break;
default:
$colour = 'D2BEAA';
break;
}
$data[$row['extension']] = array(
'user' => $row['user'],
'status' => $status,
'conf_exten' => $row['conf_exten'],
'seconds' => ( time() - $epoch_sec ),
'campaign_id' => $row['campaign_id'],
'user_group' => $row['user_group'],
'full_name' => $row['full_name'],
'calls_today' => $row['calls_today'],
'lead_id' => $row['lead_id'],
'colour' => $colour
);
}
Now for example when the Extension is SIP/P023 everything works all right, but since the users can use both extension SIP/P023 and SIP/B023 I need to find a wait that this you have the same output
Screenshot of what i have
Now i need to make a single square with the result of either one of the extension witch is active (they cant ever be active in the same time)
I dont know if i have explained myself but i hope at least
Have you tried the API? here: http://www.vicidial.org/docs/NON-AGENT_API.txt
Look for the agent_status section. That will give you realtime stats of the user. So all you have to do is set your script to refresh that at whatever interval you want. Let me know if you need more help with the api.

sqlite3 replacement for sqlite_has_more

First of thank you for your help.
The code piece "while (sqlite_has_more($dres))" is using sqlite2 and I need sqlite3. If there isn't a replacement for has_more is there another code I can use to still Find whether or not more rows are available?
F.Y.I. The server updated their stuff which included their sqlite and now I have to fix this last peice of code to get the schedule to populate and not give me this error.
Fatal error: Non-static method SQLite3::open() cannot be called statically in /home/server/public_html/current-list.php on line 57
$row_num = 0;
if ($dbh = SQLite3::open($sked_path))
{
$qsql = "SELECT rowid,* FROM sked ORDER BY sk_dow_num, sk_time_start, sk_time_end";
$dres = SQLite3::query($dbh, $qsql);
if (SQLite3::num_Rows($dres) > 0)
{
$last_dow = "";
$last_start = "0000";
$last_end = "0000";
while (sqlite_has_more($dres))
{
$ska = Sqlite3Result::fetchArray($dres, SQLITE3_ASSOC);
$rid = $ska['rowid'];
$dow = $ska['sk_dow_name'];
$start = $ska['sk_time_start'];
$end = $ska['sk_time_end'];
$title = preg_replace("/<br\s*\/*>/", " ", $ska['sk_show_title']);
$show_dow = strtoupper($dow);
$show_start = strtoupper(formatTimeAmPm($start));
$show_end = strtoupper(formatTimeAmPm($end));
$show_style = "";
if (stristr($title, "Encore Show"))
$show_style = " class=\"$text_style\"";
Something like ...
<?php
$dbh = new SQLite3;
if ( !$dbh->open($sked_path) ) {
trigger_error('...error handling...', E_USER_ERROR);
}
else {
$dres = $dbh->query('
SELECT
rowid,*
FROM
sked
ORDER BY
sk_dow_num, sk_time_start, sk_time_end
');
if ( !$dres ) {
trigger_error('...error handling...', E_USER_ERROR);
}
else {
$ska = $dres->fetchArray(SQLITE3_ASSOC);
if ( !$ska ) {
onNoRecords();
}
else {
do {
doSomethingWithRowData($ska);
}
while( false!=($ska=$dres->fetchArray(SQLITE3_ASSOC)) );
}
}
}
(completely untested)

Cannot read array in nested foreach after changing host

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);

Categories