i would like to import a txt-file with datas for a project. The file have different sections.
$file = fopen( $filename, "r" );
$object = array();
while( !feof( $file ) )
{
$line = fgets($file);
$items = explode( ";", $line );
//Import the global values
if( count($items) == 1 )
{
$arraySection = str_replace("#", "",trim($items[0]) );
}
else if ( count($items) == 3 )
{
$object[$arraySection][$items[0]] = $items[1];
}
else if ( count($items) == 4 )
{
//$object[$arraySection][] = array("gewerknummer" => $items[1], "gewerkbezeichnung" => $items[2]);
}
//Import the articel
else if ( count($items) > 4 )
{
if( $items[0] == "Artikel-Nr" )
{
$articelrow = $items;
}
else
{
$articeldetails = array();
for($i = 0; $i < count($items)-1; $i++)
{
$articeldetails[] = array($articelrow[$i]=>$items[$i]);
}
$object["artikel"] = array(
$articeldetails
);
}
}
}
//Start of import the array to the database
$arrValue = array();
for($i = 0; $i < count($object['artikel']); $i++)
{
$tArray = array();
$tArray[] = $object['Objekt']['Objektnr'];
$tArray[] = $object['SuAdresse']['SUNr'];
$tArray[] = $object['artikel'][$i][0]['Artikel-Nr'];
$tArray[] = "'" . $object['artikel'][$i][1]['Artikel']. "'";
$tArray[] = "'" . $object['artikel'][$i][2]['Beschreibung'] . "'";
$tArray[] = "'" . $object['artikel'][$i][3]['Einheit'] . "'";
$tArray[] = "'" . str_replace(",", ".", $object['artikel'][$i][4]['Preis-Pro-Einheit']) . "'";
$tArray[] = $object['artikel'][$i][5]['AnzahlParameter'];
$tArray[] = "'" . $object['artikel'][$i][6]['P1_Einheit'] . "'";
$tArray[] = "'" . $object['artikel'][$i][7]['P2_Einheit'] . "'";
$tArray[] = "'" . $object['artikel'][$i][8]['P3_Einheit'] . "'";
$tArray[] = "'" . $object['artikel'][$i][9]['MBS Artikel'] . "'";
$tArray[] = $object['artikel'][$i][10]['Status'];
$tArray[] = $object['artikel'][$i][11]['SuArtikel'];
$tArray[] = $object['artikel'][$i][12]['SuGewerke'];
$tArray[] = "'" . $object['artikel'][$i][13]['PreisStatus'] . "'";
if ( empty( $object['artikel'][$i][14]['ZulageMindermengenArtikelNr'] ) )
$tArray[] = 0;
else
$tArray[] = 0 . $object['artikel'][$i][14]['ZulageMindermengenArtikelNr'];
$arrValue[] = "(" . implode(",", $tArray) . ")";
}
$query = "INSERT INTO objekt_artikel
(
id_objekt,
id_subunternehmer,
artikelnummer,
artikel,
beschreibung,
einheit,
preis_pro_einheit,
anzahl_parameter,
p1_einheit,
p2_einheit,
p3_einheit,
mbs_artikel,
status,
su_artikel,
su_gewerk,
preis_status,
zulage_mindermengen_artikel_nummer
)
VALUES " . implode(",", $arrValue);
But the articels are not added right to the multi-array, because the loop for the query creates only one insert, but when i make a var_dump of of the $object, there looks that the values all be inserted to the array.
I think i have a logic error with filling the array and reading it out.
echo count($object['artikel']) . "\n";die();
This give me the result, that only one Element in the array, but normaly it have to be over 800.
The Element in the array is the last one from the hole Articel list.
Change:
$object["artikel"] = array(
$articeldetails
);
to:
$object["artikel"][] = $articeldetails;
You're not adding to $object['artikel'] each time, you're overwriting it.
You are replacing the same variable each time you go in the while loop...
$object['artikel'] = array($articeldetails);
With this affectation, the array $object has the same cell ('artikel') replaced everytime...
Related
public function update($id, $table, $data, $exclude = array()){
$query = "UPDATE $table SET";
$fields = $values = array();
if( !is_array($exclude) ) $exclude = array($exclude);
foreach( array_keys($data) as $key ) {
if( !in_array($key, $exclude) ) {
$fields[] = "`$key`";
$values[] = "'" . $this->db->real_escape_string($data[$key]) . "'";
}
$fields = implode(" ", $fields);
$values = implode(" ", $values);
$query .= $fields . "=" . $values . ",";
}
$query = $query . "WHERE id = '".$id."' ";
if(!$this->db->query($query)){
echo "Something wrong with query ";
}
else{
echo "successfully updated";
}
}
Got error
Fatal error: [] operator not supported for strings
Tweaked code from add function which worked. Wanted to have fields and values updated dynamically without using variables, i.e. $_POST['address'].
$query .= $fields . "=" . $values . ", ";
seem not to be working. Not sure what cause the error: Fatal error: [] operator not supported for strings. How to insert field = value in sql query?
Use like this
if( !is_array($exclude) ) $exclude = array($exclude);
foreach( array_keys($data) as $key ) {
if( !in_array($key, $exclude) ) {
$query .= $key . "='" . $data[$key] . "' ,";
}
}
$query = substr($query,0,strlen($query)-1);
$query = $query . " WHERE id = '".$id."' ";
Look at the foreach loop!!!
foreach( array_keys($data) as $key ) {
if( !in_array($key, $exclude) ) {
$fields[] = "`$key`";
$values[] = "'" . $this->db->real_escape_string($data[$key]) . "'";
}
$fields = implode(" ", $fields); // Mistake done here
$values = implode(" ", $values); // Mistake done here
$query .= $fields . "=" . $values . ",";
}
Change your those two line and the next line outside the loop. May be this solve your problem.
foreach( array_keys($data) as $key ) {
if( !in_array($key, $exclude) ) {
$fields[] = "`$key`";
$values[] = "'" . $this->db->real_escape_string($data[$key]) . "'";
}
}
$fields = implode(" ", $fields);
$values = implode(" ", $values);
$query .= $fields . "=" . $values . ",";
Follow my code. Where no need implementation implode() function. I have changed your function code. try it.
public function update($id, $table, $data, $exclude = array()){
$query = "UPDATE $table SET";
$fields = $values = array();
if( !is_array($exclude) ) $exclude = array($exclude);
foreach( array_keys($data) as $key ) {
if( !in_array($key, $exclude) ) {
$queryArr[] = $key . "='" . $this->db->real_escape_string($data[$key]);
}
}
$query = implode(" ,", $queryArr);
$query = $query . "WHERE id = '".$id."' ";
if(!$this->db->query($query)){
echo "Something wrong with query ";
}
else{
echo "successfully updated";
}
}
I am trying to create a class to save time on cleaning up my variables before sending them to the database to prevent sql injections. The basic systems is working now but i cant seem to get a where/or statement implemented. Does anyone know how to add this?
<?php
class Database {
private $db = '';
private $database = '';
function __construct($settings) {
$this->db = new mysqli('127.0.0.1', $settings['mysql_user']['username'], $settings['mysql_user']['password']);
$this->database = $settings['mysql_user']['database'];
print_r('Database Loaded!<br/>');
}
public function query($method, $database, $rows, $params, $where = array(), $or = array()) {
$count = 0;
$amount = count($rows);
$final_rows = '';
$final_data = '';
$bind_names = array();
$bind_names[0] = '';
$param_types = array(
"int" => "i",
"string" => "s",
"double" => "d",
"blob" => "b"
);
switch($method) {
case 'INSERT':
foreach ($rows as $row) {
$count = $count + 1;
$final_rows .= '`' . $row . '`' . ($count != $amount ? ', ' : '');
$final_data .= '?' . ($count != $amount ? ', ' : '');
}
$stmt = $this->db->prepare('INSERT INTO `' . $this->database . '`.`' . $database . '` (' . $final_rows . ') VALUES (' . $final_data . ')');
for ($i = 0; $i < count($params); $i++)
{
$bind_name = 'bind'.$i;
$$bind_name = $params[$i][1];
$bind_names[0] .= $param_types[$params[$i][0]];
$bind_names[] = &$$bind_name;
}
call_user_func_array( array ($stmt, 'bind_param'), $bind_names);
return $stmt->execute();
break;
case 'UPDATE':
foreach ($rows as $row) {
$count = $count + 1;
$final_rows .= '`' . $row . '`' . ($count != $amount ? ', ' : '');
$final_data .= '?' . ($count != $amount ? ', ' : '');
}
$stmt = $this->db->prepare('UPDATE `' . $this->database . '`.`' . $database . '` SET ' . $final_rows . '');
for ($i = 0; $i < count($params); $i++)
{
$bind_name = 'bind'.$i;
$$bind_name = $params[$i][1];
$bind_names[0] .= $param_types[$params[$i][0]];
$bind_names[] = &$$bind_name;
}
call_user_func_array( array ($stmt, 'bind_param'), $bind_names);
return $stmt->execute();
break;
case 'REPLACE':
foreach ($rows as $row) {
$count = $count + 1;
$final_rows .= '`' . $row . '`' . ($count != $amount ? ', ' : '');
$final_data .= '?' . ($count != $amount ? ', ' : '');
}
$stmt = $this->db->prepare('REPLACE INTO `' . $this->database . '`.`' . $database . '` (' . $final_rows . ') VALUES (' . $final_data . ')');
for ($i = 0; $i < count($params); $i++)
{
$bind_name = 'bind'.$i;
$$bind_name = $params[$i][1];
$bind_names[0] .= $param_types[$params[$i][0]];
$bind_names[] = &$$bind_name;
}
call_user_func_array( array ($stmt, 'bind_param'), $bind_names);
return $stmt->execute();
break;
}
}
}
?>
Going to make a few assumptions, but first I'll recommend you use an ORM before whipping up your own solution. Here's a good list of PHP libraries (I've linked to the database sections, which includes some very well done stand-alone ORMs https://github.com/ziadoz/awesome-php#database)
That being said I'm going to assume the $where and $or arrays are both for the WHERE construct and the items in $where are combined via AND and the $or is combined via OR.
Because you didn't describe what kind of output you were looking for I'm also assuming your $where and $or are key/value pairs which translates to "key=value AND key=value AND (key=value OR key=value)".
DISCLAIMER: This example is kind of hacky, but is the shortest/simplest way to get the example across.
$whereQuery = '';
foreach ($where as $key => $value) {
$whereQuery .= "$key = $value AND";
}
if ($or !== array()) {
$whereQuery .= '(';
foreach ($or as $key => $value) {
$whereQuery .= "$key = $value OR";
}
}
if ($whereQuery !== '') {
if (($temp = strlen($whereQuery) - strlen('AND')) >= 0 && strpos($whereQuery, 'AND', $temp) !== false) {
$whereQuery = substr($whereQuery, -4);
} else {
$whereQuery = substr($whereQuery, -3) . ')';
}
$whereQuery = "WHERE $whereQuery";
}
You can then stick the $whereQuery at the end of an UPDATE or SELECT. Even if $where and $or are empty it'll still work.
You could move the loops into functions and make it recursive if the $value was another array so you could create more complex WHERE statements.
I am trying to write some PHP that fits in to a larger method so that I can dynamically create a MySQL query.
I haven't included the code to the larger method that contains this code because I think the logic of this bit is self-contained.
So, I have a multi-dimensional array:
$where=array(array('username', 'pid', 'name'), array('=','<=', '='), array('alex',2,'james'));
which when I print_r() shows this structure:
Array
(
[0] => Array
(
[0] => username
[1] => pid
[2] => name
)
[1] => Array
(
[0] => =
[1] => <=
[2] => =
)
[2] => Array
(
[0] => alex
[1] => 2
[2] => james
)
)
What I would like to do if use the first value in each second level array to build up the start of the query such as
SELECT * FROM table WHERE username = alex
and then use the other values to build up the query such as (depending upon the number of items in the arrays)
SELECT * FROM table WHERE username = alex AND pid <= 2 AND name = james
Below is the code I have written
if (is_array($where[0])){
$i=0;
$field = $where[0][$i];
$operator = $where[1][$i];
$value= $where[2][$i];
$sql= "SELECT * FROM table WHERE {$field} {$operator} {$value}";
while($i=0 ) {
print $sql;
$i++;
}
while($i>0 AND $i< sizeof($where[0]))
$field = $where[0][$i];
$operator = $where[1][$i];
$value= $where[2][$i];
print $sql .= " AND {$field} {$operator} {$value}";
$i++;
}
However this prints out just one query
SELECT * FROM table WHERE username = alex AND username = alex
I am using PDO so in reality {$value} is replaced by ? and bound elsewhere in the method. I've just shown it here in full.
$sql = 'SELECT * FROM table WHERE';
for($i = 0; $i < count($where[0]); $i++){
$sql .= " {$where[0][$i]} {$where[1][$i]} {$where[2][$i]} AND";
}
$sql = substr($sql, 0, strlen($sql) - 4);
I personally would however save your statements like this:
$array = array('username = alex', 'pid <= 2');
If you needed the different parts of the statements, you could just do
explode(' ', $array[num]);
$companyFilter = "";
$auth = getFormulaAuth();
$companyFilter = "AND company_id = {$auth['company_id']} ";
$arguments = func_get_args();
if ($WhereFilterName_xxx) {
} else {
$db = new Database();
$this_get_table_form = getFormulaFormDetails($FormName);
$tbfields_data = Formula::getTBFields($this_get_table_form["id"], $db);
$q_string = "SELECT * FROM `" . $this_get_table_form["form_table_name"] . "`";
$valid_param_check = count($arguments) - 2;
$cache_key = "*";
if ($valid_param_check >= 1 && $valid_param_check % 3 == 0) {
$found_indexes = array();
$q_string_where = " WHERE ";
$search = " (NOT EXISTS(SELECT * FROM tbtrash_bin WHERE record_id = " . $this_get_table_form["form_table_name"] . ".id
AND form_id = " . $this_get_table_form["id"] . "
AND table_name='" . $this_get_table_form["form_table_name"] . "')) AND ";
$q_string_where .= $search;
for ($i = 2; $i < count($arguments); $i+=3) {
$field_key = $arguments[$i];
$operator = $arguments[$i + 1];
$value = $arguments[$i + 2];
if ($i > 2) {
$q_string_where .= " AND ";
}
$q_string_where .= " `" . $field_key . "` " . $operator;
if (($tbfields_data["" . $field_key]["field_input_type"] == "Number" || $tbfields_data["" . $field_key]["field_input_type"] == "Currency") || strtoupper($operator) == "IN") {
$q_string_where .= " " . $value . " ";
} else {
$q_string_where .= " '" . $value . "' ";
}
$q_string_orderby .= $q_string_where;
$sort_by = isset($_GET['s']) ? $_GET['s'] : false;
switch ($sort_by) {
case $tbfields_data;
break;
default:
$sort_by = 'DateCreated';
}
$q_string_orderby .= ' ORDER BY '.$sort_by.' ';
$direction = isset($_GET['d']) ? $_GET['d'] : false;
if ($direction != 'ASC' && $direction != 'DESC')
$direction = 'DESC';
$q_string_orderby .= $direction;
$res = $db->query($q_string_orderby);
$results = array();
if ($res) {
while ($r = mysql_fetch_assoc($res)) {
$results[] = $r;
}
}
$cache_key.="::" . $field_key . "::" . $operator . "::" . $value . "::" . $q_string_orderby;
}
$q_string .= $q_string_orderby;
}
$this_record = Formula::getLookupValue("formula_lookup_where_array", $this_get_table_form, $q_string, $cache_key);
array_push($GLOBALS['formula_executed_data_collector']['collected_form_id'], array(
"form_id" => $this_get_table_form['id'],
"where" => $q_string_where,
"function_name" => "Total",
"whole_query" => $q_string
));
$rslt = array_values(array_map(function($a) use($ReturnField) {
if (gettype($ReturnField) == "array") {
$array_collector = array();
foreach ($ReturnField as $key => $value) {
$array_collector[$value] = $a[$value];
}
return $array_collector;
} else if ($ReturnField == "*") {
return $a;
} else {
return $a[$ReturnField];
}
}, $this_record));
return $rslt;
}
}
I'm using var_export to dump output to logs when errors occur. However since the result is in pure text, I don't get a chance to push it through some sort of library like krumo so I can interactively explores the output.
What methods do people have to deal with making var_export text more readable?
Here is my function, it works well for multidimensional arrays:
function VE($varname, $varval, $short_syntax=true, $tag = ' ', $comma='', $end_line="\r\n") {
$res = '';
if($short_syntax){
$begin_array = '[';
$end_array = ']';
} else {
$begin_array = 'array(';
$end_array = ')';
}
$arr = explode('/',$varname);
$dim =count($arr)-1;
$lastKey = end($arr);
if (! is_array($varval)){
if( is_string($varval)) $varval = "'$varval'";
$res .= str_repeat($tag,$dim) . $lastKey . ' => ' . $varval . $comma . $end_line;
}else{
$res .= str_repeat($tag,$dim) . $lastKey . ' => ' . $begin_array . $end_line;
$count_varval = 0;
$dim_varval = count($varval);
foreach ($varval as $key => $val){
$count_varval++;
if($count_varval<$dim_varval) $commma=','; else $commma='';
if( is_string($key)) $key = "'$key'";
$res .= VE ($varname . "/" . $key , $val, $short_syntax, $tag, $commma);
}
$res .= str_repeat($tag,$dim) . $end_array . $comma . $end_line;
}
return $res;
}
$bigarray = array(); // your array
$bb = VE ('$bigarray', $bigarray);
echo "<pre>$bb</pre>";
I hope it helps ;)
I am trying to implode some variables and insert them into a MySql database, but for some reason it is not working. I have been trying for hours and I''m just not sure what I'm doing wrong.
If you can help it would be much appreciated.
$AddressString = "address1,address2,address3,address5,postcode";
$AddressSplit = explode( ",", $AddressString ); //split the address string
$StringLength = count( $AddressSplit ) - 1;
$s = 0; //trim any white spaces from the address string
while ( $s < count( $AddressSplit ) ) {
$AddressSplit[$s] = trim( $AddressSplit[$s] );
$s++;
}
//Create the Values to insert into DB
$MysqlValues = implode( "','", $AddressSplit );
$MysqlValues = "'$MysqlValues'";
$NumberVals = count( $AddressSplit );
$t = 1;
while ( $t < $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
$TableNames = implode( ", ", $ad );
mysql_query( "INSERT INTO pstc_add_main (" . $TableNames . ",add10,date)
VALUES (" . $MysqlValues . ",'$cdate')" );
}
Because you start making the field names 1 based, your are one field short!
In the end you must end with a equal number of fields and values.
Try this:
$t = 0;
while ( $t < $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
Or, if you do not want the first field to be "add", change it like this:
$t = 1;
while ( $t <= $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
Of course, it would have been a easy test to do:
$sql = "INSERT INTO pstc_add_main (" . $TableNames . ",add10,date)
VALUES (" . $MysqlValues . ",'$cdate')";
var_dump($sql);
mysql_query($sql);
Not tested,
I doubt you change,
$MysqlValues = implode("','", $AddressSplit);
to
$MysqlValues = implode(",", $AddressSplit);
Just use
$MysqlValues = implode( ",", $AddressSplit );
and try to edit the code like
mysql_query( "INSERT INTO pstc_add_main (".$TableNames." ,add10,date)
VALUES (" . $MysqlValues . ",$cdate)" );