I have a .txt file that logs some information. I want to load it to MySQL table, but I have a following problem: the .txt log file isn't uniform, meaning it looks something like this:
04092012 16:07:34.988 stuff1 stuff2 username1 importantStuff
04092012 16:08:12.145 stuff1 stuff2 stuff3 username2 stuff4 importantStuff
Important thing to say is that all usernames begin with the same characters, just like here. I know that I'm supposed to use something like:
$lines=file(log.txt);
foreach($lines as $v) {
$values = explode(' ',$v);
...
But I do not know how to transfer only date, time, username and importantStuff into MySQL table.
I appreciate any help I can get. Thanks in advance.
$file = file_get_contents('log.txt');
$lines = explode("\n", $file);
foreach($lines as $v) {
$values = explode(' ',$v);
$all = count($values);
$user = preg_match_all('/(user\w+\b)/', $v, $matches); // it will match all usernames that start with "user"
$time = $values[1];
$username = $matches[0][0];
$stuff = $values[($all-1)];
$date = $values[0];
$query = "INSERT INTO `MyTable` ('".$date."', '".$time."', '".$username."', '".$stuff."')";
}
If you are sure that the stuff parts do not contain the same pattern as the username part you can use something like:
$lines=file(log.txt);
foreach($lines as $v) {
$values = explode(' ',$v);
$date = "";
$time = "";
$important = "";
$username = "";
foreach($values as $cnt => $val){
if($cnt == 0){
$date = $val;
} else if($cnt == 1){
$time = $val;
} else if(substr($val, 0, 8) == 'username'){
$username = $val;
}
$important = $val;
}
$query = "INSERT INTO logtable VALUES ('$date', $time', '$username', '$important')";
}
Related
I have the follow problem:
I have differents arrays, each array contain a list of items.
I try to insert in database but each item of list result togheter.
This is my code:
(i use preg_replace for delete between items)
$codice = preg_replace('/(<br>)+$/', '', $_POST['jcitemcodice']);
$prodotto = preg_replace('/(<br>)+$/', '', $_POST['jcitemname']);
$quantita = preg_replace('/(<br>)+$/', '', $_POST['jcitemqty']);
$prezzo = preg_replace('/(<br>)+$/', '', $_POST['jcitemprezzo']);
$a1 = array("$codice","$prodotto","$quantita","$prezzo");
$res = implode("','" ,$a1);
$sql = "INSERT INTO test (codice,prodotto,quantita,prezzo) VALUES ('$res')";
mysql_query($sql);
Making echo of query the result is:
INSERT INTO test (codice,prodotto,quantita,prezzo) VALUES ('SUT03M SUT02M','Arrabbiata Albahaca','12 6','1.25 1.3')
but for to be correct i need the result:
INSERT INTO test (codice,prodotto,quantita,prezzo) VALUES ('SUT03M','Arrabbiata','12','1.25'), VALUES ('SUT02M','Albahaca','6','1.3')
$codice contain: SUT03M SUT02M
$prodotto contain: Arrabbiata Albahaca
$quantita contain: 12 6
$prezzo contain: 1.25 1.3
I have try a lot of codes looking around but always same result.
Thanks you.
Assuming codice, prodotto, quantita, prezzo don't contain value with _ (underscore), you can explode their content separated by it:
//Change existing tag with defined delimiter
$d = "_";//delimiter
$codice = preg_replace('#<[^>]+>#', $d, $_POST['jcitemcodice']);
$prodotto = preg_replace('#<[^>]+>#', $d, $_POST['jcitemname']);
$quantita = preg_replace('#<[^>]+>#', $d, $_POST['jcitemqty']);
$prezzo = preg_replace('#<[^>]+>#', $d, $_POST['jcitemprezzo']);
//replace space in quantita and in prezzo with the delimiter
$quantita = preg_replace(' ', $d, $quantita);
$prezzo = preg_replace(' ', $d, $prezzo);
//Separate data
$tCodice = explode($d, $codice);
$tProdotto = explode($d, $prodotto);
$tQuantita = explode($d, $quantita);
$tPrezzo = explode($d, $prezzo);
//Formulate values string
$values = "";
foreach($tCodice as $key => $_codice){
if($_codice > ""){
$a1 = array(trim($tCodice[$key]), trim($tProdotto[$key]), trim($tQuantita[$key]), trim($tPrezzo[$key]));
$res = implode("','" ,$a1);
if($values != ""){
$values .= ", ";
}
$values .= "('".$res."')";
}
}
$sql = "INSERT INTO test (codice,prodotto,quantita,prezzo) VALUES $values";
echo $sql;
Please improve this for more custom data from you $_POST
This is a generalized code and no matter how many variables u have and it will add null if no match found in the strings u were already split.
$codice = "SUT03M SUT02M";
$prodotto = "Arrabbiata";
$quantita = "12 6";
$prezzo = "1.25 1.3";
$column_keys = array("codice","prodotto","quantita","prezzo");
$res = array();
$c = 0;
$sql = "";
$max = array("k" => 0,"v" => "");
foreach ($column_keys as $key => $value) {
$res[$value] = explode(" ",${$value});
$c = count($res[$value]);
if($c > $max["k"])
$max = array("k" => $c,"v" => $value);
}
if($max["k"] > 0){
$sql = "INSERT INTO test (".implode($column_keys,",").") VALUES ";
for ($i=0; $i < $max["k"] ; $i++) {
$ar = array();
foreach ($column_keys as $key => $value)
$ar[] = isset($res[$value][$i]) ? $res[$value][$i] : "NULL";
$adstrng = $i>0 ? ",":"";
$sql.= $adstrng."(".implode($ar,",").")";
}
}
echo $sql;
As like #tadman commented don't use deprecated codes and try to do in
updated standards like PDO
Php code
<?php
$d1 = "a:1,b:2,c:3,d:4"; //field number variable.. sometimes 4 or 10
$d2 = explode(',', $d1);
foreach ($d2 as $key => $value) {
$arr1 = explode(':',$d2[$key]);
foreach ($arr1 as $key1 => $value1) {
$arr1[] = $key1;
}
echo $arr1[0] . "," . $arr1[1] . ",";
}
?>
Result
a,1,b,2,c,3,d,4,
Fields (a,b,c,d) (field number variable.. sometimes 4 or 10..)
Values (1,2,3,4)
Expected result
Insert into Table1 (a,b,c,d) values (1,2,3,4)
How can i do to make this result ? (it would be good if it is a complete example)
Thanks for all answers
I know preg_split() will do the task fine. But last day when I got the similar problem I did this solution with the help of http://php.net/manual/en/function.explode.php#111307
function multiexplode ($delimiters,$string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return $launch;
}
$d1 = "a:1,b:2,c:3,d:4";
$result = implode(',',multiexplode(array(",",".","|",":"),$d1));
echo $result;
See demo : https://eval.in/871705
Edit: As per comment by SO
$d1 = "a:1,b:2,c:3,d:4"; //field number variable.. sometimes 4 or 10
$d2 = explode(',', $d1);
$result = [];
foreach ($d2 as $key => $value) {
list($k,$v) = explode(':',$value);
$result[$k] = $v;
}
print '<pre>';
print_r($result);
print '</pre>';
echo "INSERT INTO table1 (".implode(', ',array_keys($result)). ") VALUES (".implode(', ',array_values($result)). ")";
In recent PHP versions you can destructure the result of explode() on $d2[$key] (you should improve your naming, it helps!) into two separate arrays like so:
$keys = $values = [];
foreach (explode(',', $d1) as $parameter)
[$keys[], $values[]] = explode(':', $parameter);
var_dump($keys, $values);
var_dump(array_combine($keys, $values));
After that you can simply build that into a query. However, it seems like your data might be user-provided so you should be very wary of that data. You seem to be almost introducing a SQL injection vulnerability in your code.
I suggest checking the $keys array against a whitelist and after that properly escaping all $values before using any of this in a query. You may find some info here: PDO with INSERT INTO through prepared statements
You can use preg_split.
$output = preg_split( "/ (,|:) /", $input );
Next, you can do a check in a loop.
foreach ($output as $value)
{
if(is_number($value))
$keys[] = $value;
else
$values[] = $value;
}
Since the string is close to json format i think making it a true json and decode it means no looping or exploding is an efficient solution.
$d1 = "a:1,b:2,c:3,d:4";
$d1 = "{\"".str_replace(array(",",":"),array('","','":"'), $d1)."\"}";
$arr = json_decode($d1, true);
$table = array_keys($arr);
$values = array_values($arr);
Var_dump($table);
Var_dump($values);
https://3v4l.org/Yqrbe
Edit; if you need the string you named as expected result use this:
$str ="Insert into Table1 (". Implode(",", $table) .") values (" . Implode(",", $values).")";
Echo $str;
Used below code.
Just little bit changes in your code this is working fine.
$d1 = "a:1,b:2,c:3,d:4"; //field number variable.. sometimes 4 or 10
$d2 = explode(',', $d1);
$colums = $values = array();
foreach ($d2 as $key => $value) {
$arr1 = explode(':',$value);
$colums[] = "`".$arr1[0]."`";
$values[] = "'".$arr1[1]."'";
}
$sql = 'insert into `Table1` ('.implode(",",$colums).') values ('.implode(",",$values).')';
Try with following logic:
foreach ($d2 as $key => $value) {
$arr1 = explode(':', $value);
if (count($arr1) == 2){
$arr[$arr1[0]] = $arr1[1];
}
}
Get all fields and values as comma separated:
$fields = array_keys($arr);
¢values = array_values($arr);
And use these variables into your query:
$fields = implode(",", array_keys($arr));
$values = implode(",", array_values($arr));
$query = "INSERT INTO Table1 (".$fields.") VALUES (".$values.")";
Running snipet: https://ideone.com/EXAPOt
I have a log file from firewall, and I want to store it in mysql database using php, I have used the same key for database, I want to separate the log data in array key=value format and again there is space between each key values, and there are some countries which contain spaces between the coutry name. So how can I complete my task. And for the idea here you can see the log file:
date=2016-04-11 time=11:26:29 logid=0000000013 type=traffic
subtype=forward level=notice vd=root srcip=10.10.24.232 srcport=35321
srcintf="port2" dstip=173.252.74.22 dstport=443 dstintf="wan1"
poluuid=426a22f0-b2d8-51e5-4e06-b3d158ed335f sessionid=11469008
proto=6 action=deny policyid=33 dstcountry="United States"
srccountry="Reserved" trandisp=snat transip=202.166.220.127
transport=35321 service="HTTPS" appid=15832 app="Facebook"
appcat="Social.Media" apprisk=medium applist="GEN-ACC-FBBLK"
appact=drop-session duration=22 sentbyte=120 rcvdbyte=60 sentpkt=2
utmaction=block countapp=1 utmref=62972-2591658 date=2016-04-11
time=11:26:29 logid=0000000013 type=traffic subtype=forward
level=notice vd=root srcip=10.10.37.60 srcport=43857 srcintf="port2"
dstip=202.166.193.187 dstport=443 dstintf="wan1"
poluuid=426a22f0-b2d8-51e5-4e06-b3d158ed335f sessionid=11373387
proto=6 action=close policyid=33 dstcountry="Nepal"
srccountry="Reserved" trandisp=snat transip=202.166.220.127
transport=43857 service="HTTPS" appid=41542 app="SSL_TLSv1.0"
appcat="Network.Service" apprisk=medium applist="GEN-ACC-FBBLK"
appact=detected duration=424 sentbyte=1320 rcvdbyte=1582 sentpkt=10
rcvdpkt=16 utmaction=allow countapp=2 utmref=62972-2591632
Finally I can correct it myself, I hope it will help to others too:
$str = file_get_contents($_FILES["file"]["tmp_name"]);
$str1 = str_replace("\"", "", ($str) );
$vals=split('date=', $str1);
array_shift($vals);
$finalArray = array();
$j = 0;
foreach($vals as $v){
$finalArray[$j]["date"] = substr($v, 0, 10);
//var_dump($v);
$tempString = substr($v, 11);
$tempArr = explode(" ", $tempString);
$prevTemp = "";
foreach($tempArr as $i){
$tmp = explode("=",$i);
if(!isset($tmp[1])){
$finalArray[$j][$prevTemp] = $finalArray[$j][$prevTemp]." ".$i;
}
else{
$finalArray[$j][$tmp[0]] = isset($tmp[1]) ? $tmp[1]: '';
$prevTemp = $tmp[0];
}
}
$j++;
}
//var_dump($finalArray);
//die();
$totalQuery = '';
foreach($finalArray as $val){
if(is_array($val)){
$queryText = 'INSERT INTO `intrulog` SET';
$i = 0;
foreach($val as $k=>$v){
if(isset($v) && !empty($v)){
if($i)
$queryText .= ',';
$queryText .= " `{$k}` = '{$v}' ";
$i++;
}
}
$queryText .= ";<br>";
$totalQuery .= $queryText;
}
}
//echo $queryText;
}
To import and verify emails I use this script, but I have a problem. The first email preg_match doesn't work. Do you have any ideas?
$arr_csvfields = array(email, name);
$lines = file('uploads/'.$file);
$dataline = array();
foreach ($lines as $line) {
$dataline[] = $line;
}
for($i = 0; $i < $alllines; $i++) {
$data = $datenzeilen[$i];
$csvdata = explode(';',$data);
$newdata = array_combine($arr_csvfields, $csvdata);
$emailadress = str_replace(array("\r\n","\n\r", "\n", "\r"),'',trim($newdata['email']));
if(preg_match("/^[a-zA-Z0-9_.-]+#[a-zA-Z0-9][a-zA-Z0-9-.]+\.([a-zA-Z]{2,6})$/",$emailadress) == true){
echo $emailadress;
}
}
If I make an echo $i.' - '.$emailadress in the loop. I see the first email but the first mail will not work. It allways says false or so. All other works. If I change in the csv the first and the second. It’s the self problem. So allways the ID 0 will not work.
There are a few issues I see. Here is my cleanup of your code:
$arr_csvfields = array('email', 'name');
$lines = file('uploads/'.$file);
$dataline = array();
foreach ($lines as $line) {
$dataline[] = $line;
}
for($i = 0; $i < $alllines; $i++) {
$data = $datenzeilen[$i];
$csvdata = explode(';',$data);
$newdata = array_combine($arr_csvfields, $csvdata);
$emailadress = str_replace(array("\r\n","\n\r", "\n", "\r"),'',trim($newdata['email']));
if(preg_match("/^[a-zA-Z0-9_.-]+#[a-zA-Z0-9][a-zA-Z0-9-.]+\.([a-zA-Z]{2,6})$/",$emailadress)){
echo $emailadress;
}
}
First you are setting this:
$arr_csvfields = array(email, name);
I assume you want email & name to be column headers. You can’t just place those words in there without quotes. PHP will interpret that as a constant if you do that I believe? Anyway I changed that to this:
$arr_csvfields = array('email', 'name');
I believe this $arr_csvfields issue is the cause of the first e-mail failing.
Also, you do a check with your preg_match like this:
if(preg_match("/^[a-zA-Z0-9_.-]+#[a-zA-Z0-9][a-zA-Z0-9-.]+\.([a-zA-Z]{2,6})$/",$emailadress) == true){
There is no reason for the preg_match to have the == true. The condition action itself will handle that. So I changed that to this:
if(preg_match("/^[a-zA-Z0-9_.-]+#[a-zA-Z0-9][a-zA-Z0-9-.]+\.([a-zA-Z]{2,6})$/",$emailadress)){
That said, I still don’t understand what $arr_csvfields is for. So I recommend you change this line:
$newdata = array_combine($arr_csvfields, $csvdata);
To this:
$newdata = $csvdata;
Or perhaps change these two lines:
$newdata = array_combine($arr_csvfields, $csvdata);
$emailadress = str_replace(array("\r\n","\n\r", "\n", "\r"),'',trim($newdata['email']));
To this:
// $newdata = array_combine($arr_csvfields, $csvdata);
$emailadress = str_replace(array("\r\n","\n\r", "\n", "\r"),'',trim($csvdata['email']));
I am dancing around the issue of $newdata, $arr_csvfields & $csvdata because I do not know the logic of your logic code, but it’s the best I can do without having to rewrite the rest of your code. I also do not understand what $alllines is or even what $dataline is. But here is another chunk of code to test based on this:
$arr_csvfields = array('email', 'name');
$lines = file('uploads/'.$file);
$dataline = array();
foreach ($lines as $line) {
$dataline[] = $line;
}
for($i = 0; $i < $alllines; $i++) {
$data = $datenzeilen[$i];
$csvdata = explode(';',$data);
// $newdata = array_combine($arr_csvfields, $csvdata);
$emailadress = str_replace(array("\r\n","\n\r", "\n", "\r"),'',trim($csvdata['email']));
if(preg_match("/^[a-zA-Z0-9_.-]+#[a-zA-Z0-9][a-zA-Z0-9-.]+\.([a-zA-Z]{2,6})$/",$emailadress)){
echo $emailadress;
}
}
So I have this sample string:
?items=3744130|1^356221|2^356222|1
extracted from a URL:
http://www.example.com/process.php?items=3744130|1^356221|2^356222|1
I need to convert it into this, and for the life of me I'm getting stuck.
?items=model_1=3744130&qty_1=1&model_2=356221&qty_2=2&model_3=356222&qty_3=1
I've gotten this far but that's it.
$url = substr($_SERVER['QUERY_STRING'],6);
$query = explode('^', $url);
echo http_build_query($query, 'model_');
Output currently is:
model_0=1234435%7C9&model_1=56788%7C9&model_2=6758765%7C9&model_3=3736543%7C9
How can I get the first set to be model_1 instead of the default model_0?
Thanks
You need to build the array with keys before passing it to http_build_query() if you want the numbering to start with 1.
$arr = array();
$count = 1;
foreach (explode('|', $_GET['items']) as $item) {
$elements = explode('^', $item);
if (count($elements) == 1) {
$arr["model_$count"] = $elements[0];
$arr["qty_$count"] = 1;
}
else {
$arr["model_$count"] = $elements[1];
$arr["qty_$count"] = $elements[0];
}
$count++;
}
$query = http_build_query($arr);
A quick patch should be
....
$url = substr($_SERVER['QUERY_STRING'],6);
$query = explode('^', $url);
array_unshift($query,'placeholder');
$result=http_build_query($query, 'model_');
$result = substr($result, 19);
....
Try this:
$items = explode('^', $_GET['items']);
$query = '';
foreach ($items as $key => $val) {
list($model, $qty) = explode('|', $val);
$query .= '&model_'.($key+1).'='.urlencode($model);
$query .= '&qty_'.($key+1).'='.urlencode($qty);
}
echo substr($query, 1);