I'm creating a dynamic lead capture script.
The form passes the table name, and the rest of the post data.
I'm looking for a way to collect all the post inputs and insert that into a MySQL table without knowing the input names since each 'lead' script is different and contains different fields.
The table is already created and contains all the columns necessary for the input.
Any clean ideas?
Cheers!
A quick solution is to serialize an array of your validated post data. This will convert it into a string for storing in your Database.
You can unserialize that string to convert it back into a manageble array.
http://php.net/manual/en/function.serialize.php
The biggest downside is not having the full SQL support that you would have otherwise, by putting data into separate database fields.
I would use a combination of both techniques by putting consistant data like names, email into their own fields and unknown data into another field.
--
Try index identification (if you don't know the specific names):
$data = array_values($_POST);
$name = $data[0];
$email = $data[1];
$etc = $data[2];
--
Generate SQL string from data. Remember be vigilant with validation and ideally you should use Mysqli bind params to correcly build your query string.
foreach($_POST as $input_name => $input_value){
//do validation here
//match columns here
if($input_name=='name') $cleaned[$input_name] = $input_value;
}
$values_csv = '"'.implode('","',$cleaned).'"';
$sql = "INSERT INTO table_name VALUES ($values_csv);";
Related
I have an array of strings and I need to append it in a spreadsheet, from the first to the n-th column according to the size of the array.
The strings could represent several type of values, e.g. numbers, dates and so on, so they must be put in the sheet as user entered to keep their meaning.
As far as I understand, the Google APIs offer two ways to append values, but none of them seems to be suitable for this case. Here's the issues I encountered:
Using Google_Service_Sheets_AppendCellsRequest
The problem with this method is that I cannot find a way to set the values as user entered. Here is a code sample:
// Build the CellData array
$values = array();
foreach( $ary_values AS $d ) {
$cellData = new Google_Service_Sheets_CellData();
$value = new Google_Service_Sheets_ExtendedValue();
$value->setStringValue($d);
$cellData->setUserEnteredValue($value);
$values[] = $cellData;
}
// Build the RowData
$rowData = new Google_Service_Sheets_RowData();
$rowData->setValues($values);
// Prepare the request
$append_request = new Google_Service_Sheets_AppendCellsRequest();
$append_request->setSheetId(0);
$append_request->setRows($rowData);
$append_request->setFields('userEnteredValue');
// Set the request
$request = new Google_Service_Sheets_Request();
$request->setAppendCells($append_request);
(full working code is here)
Even using CellData.setUserEnteredValue, the data is interpreted as string because one have to set the values using ExtendedValue.setStringValue (or the other supported methods, i.e. setBoolValue, setFormulaValue, setNumberValue).
Using spreadsheets.values.append
Using this method I can have the data rendered as user entered, but the "appending" is done in the wrong place in several cases. As stated in the documentation:
The input range is used to search for
existing data and find a "table" within that range. Values will be
appended to the next row of the table, starting with the first column
of the table.
So this method is meant to behave in a different way from the previous one, and that leads to problem for me.
This is a piece of code that should do what I want:
$body = new Google_Service_Sheets_ValueRange([
'values' => [ $array_values ]
]);
$params = [
'valueInputOption' => 'USER_ENTERED'
];
// the n-th column
$end_column = chr( ord('A') + count($array_values));
$result = $sheet_service->spreadsheets_values->append(
$fileId,
$sheetName . "!A1:" . $end_column . "1",
$body,
$params
);
Indeed, it works fine but with some exceptions, e.g.:
if the cell A1 is empty, the append method will put the values starting at column 2 (see this example to understand why).
if I have some written rows, then an empty row, then other written rows, the append method will "fill the gap" instead of putting the values after the very last written row.
Am I doing some errors? Is there a way to make what I want using either one or the other method?
To recap:
the values must be considered as user entered (e.g. a number or a date should be interpreted as such)
the values must be written in the row after the last non-empty cell, starting at column one
the append operation must be atomic (i.e. sending one request to get the last non-empty cell row and then sending another request to write data into that is not an option, because in the meantime another user could put data there)
Any advice is welcome!
I have a view that needs updating with a list of id's. So I am storing the values that have been selected to remove from the view in a session variable that then goes into the mySQL query as below. Then when the form is reset the values are also reset out of the array.
But its not working... this is what I've got.
Any help would be appreciated.
if($_POST['flag']=='flag'){
//collect deleted rows
$_SESSION['delete-row'][] = $_POST['idval'];
//Split session array
$idavls = join(',' , $_session['delete-row'];
$sqlDelete = "CREATE OR REPLACE VIEW filtetbl AS SELECT * FROM `".$page['db-name']."`.`leads_tbl` WHERE ".$_SESSION['filter-view']." AND `lead_status` = '1' AND `lead_id` NOT IN (".$idvals.") ORDER BY `lead_added`";
$result = mysql_query($sqlDelete);
if($result){
echo true;
}
else{
echo mysql_error();
}
}
$_session isnt the same as $_SESSION for a start.
Also dont use mysql_query or similar (because it isnt safe) use PDO
This is hard to correct without more information (and there are several errors - probaby cut and paste) so I'll pull apart one by one and you can go from there.
1 - $_SESSION['delete-row'][] = $_POST['idval'];
If 'idval' comes from multiple inputs (i.e. ) then it is already an array, and you should have $_SESSION['delete-row'] = $_POST['idval']; If you are looping in an array of inputs (i.e. trying to append for many posts from then it is correct)
2 - $idavls = join(',' , $_session['delete-row'];
$_SESSION (you said this was a type) and you also need a bracket/bract ar the end
$sqlDelete = "CREATE OR REPLACE VIEW filtetbl AS SELECT * FROM ".$page['db-name'].".leads_tbl WHERE ".$_SESSION['filter-view']." AND lead_status = '1' AND lead_id NOT IN (".$idvals.") ORDER BY lead_added";
Firsly this is very insecure as pointed out by allen213. Even if you don't use PDO to make safe the variable, please cast all the inputs as (int) assuming the IDs are integers, or at least wrap the input in mysql_real_escape_string().
Secondly, the logic in the question doesn't quite make sense. You say you want to remove IDs from the view, but what you are doing is recreating the view with only those IDs in $_SESSION['delete-row'] removed - so this may re-introduce IDs previously removed from the view. You'd actually need to keep $_SESSION['delete-row'] and keep adding to it to ensure the next time the view was created, then all the IDs are removed.
I hope that helps. If not, more code may be required (i.e. the form you are using the send data, anythign else that affects sessions etc.
I have this serialize data in my mySQL database
a:4:{i:0;s:7:"bvl.png";i:1;s:8:"ccop.jpg";i:2;s:11:"reyborn.png";i:3;s:13:"swopgroup.jpg";}
How can I update this data, for example I want to delete ccop.jpg?
Do not store serialized data in database.
Create a linked table consists of main_id and picture and store your image names in it.
So, you will have distinct access to them.
You have to fetch the value from the database, unserialize it, remove the element, serialize it and save again.
$remove = "ccop.jpg";
//
// get the string from the database
//
$arr = unserialize($str);
foreach($arr as $key => $value)
if ($value == $remove) unset($arr[$key]);
$str = serialize($arr);
//
// save the string back to the database
//
Instead of saving serialized list of values, it's better to have a normalized database and just do a simple DELETE FROM images WHERE object_id = ....
Ideally you need to
extract it
deserialize it
modify it
serialize it
write it back to the database.
Since you are storing it in a VARCHAR field and it is a PHP serialized array you would want to pull it out of the database unserialize and then re-update the field. You shouldn't look to MySQL to modify PHP specific information because well ... that's not what it is made for.
I am using a classified scripts and saves user_meta data in the wp_usermeta table.
The meta_key field is called user_address_info and in it there are all the data like below :
s:204:"a:7:{s:9:"user_add1";s:10:"my address";s:9:"user_add2";N;s:9:"user_city";s:7:"my city";s:10:"user_state";s:8:"my phone";s:12:"user_country";N;s:15:"user_postalcode";s:10:"comp phone";s:10:"user_phone";N;}";
I am not using all the fields on the script but user_add1, user_city, user_state and user_postalcode
I am having trouble to get the data using SQL like the example below (wordpress) :
$mylink = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10", ARRAY_A);
I would like some help here so that I will display anywhere (I dont mind using any kind of SQL queries) the requested info e.g. the user_city of current author ID (e.g. 25)
I was given the following example but I want something dynamic
<?php
$s = 's:204:"a:7:{s:9:"user_add1";s:10:"my address";s:9:"user_add2";N;s:9:"user_city";s:7:"my city";s:10:"user_state";s:8:"my phone";s:12:"user_country";N;s:15:"user_postalcode";s:10:"comp phone";s:10:"user_phone";N;}"';
$u = unserialize($s);
$u2 = unserialize($u);
foreach ($u2 as $key => $value) {
echo "<br />$key == $value";
}
?>
Thank you very much.
No, you can't use SQL to unserialize.
That's why storing serialized data in a database is a very bad idea
And twice as bad is doing serialize twice.
So, you've got nothing but use the code you've given.
I see not much static in it though.
do you experience any certain problem with it?
Or you just want to fix something but don't know what something to fix? Get rid of serialization then
i have found that the serialize value stored to database is converted to some other way format. Since the serialize data store quotes marks, semicolon, culry bracket, the mysql need to be save on its own, So it automatically putting "backslash()" that comes from gpc_magic_quotes (CMIIW). So if you store a serialize data and you wanted to used it, in the interface you should used html_entity_decode() to make sure you have the actual format read by PHP.
here was my sample:
$ser = $data->serialization; // assume it is the serialization data from database
$arr_ser = unserialize(html_entity_decode($ser));
nb : i've try it and it works and be sure avoid this type to be stored in tables (to risky). this way can solve the json format stored in table too.
Working on a pre-existing program that parses an html form that has a dynamically created number of fields, and in the interest of forward-compatibility, may not even know number of mysql columns...
I imagine that this requires creating two arrays, and comparing/re-ordering of some sort, but can't quite wrap my head around it...
Would this be something like:
A) Database Array -
1) get # of MySQL columns
2) loop through this number and get MySQL column names
B) Form Array -
1) get # of form fields
2) get form field names/values
C) Match Array -
match name.form_field[f] to name.mysql_column[c]
D) Execute Insert -
insert value of name.form_field[f] into name.mysql_column[c]
(INSERT INTO name.mysql_column[c], name.mysql_column[c+2], name.mysql_column[c+5], name.mysql_column[c+n] VALUES value(name.form_field[f]), value(name.form_field[f+9]), value(name.form_field[f+3]), value(name.form_field[f+x]))
I'm guessing the answer is something like the above, but can't quite picture the nested loops required to achieve the result...
Any possible solutions spring to mind out there?
All responses will be greatly appreciated!
Thanks,
Sean McKernan
McK66 Productions
This requires a longer answer, but I'll try a halfway decent introduction.
I suggest approaching the problem from the other direction. Ideally, the code would have it's own list of fields to insert and then go looking at the submitted data to construct the relevant rows. That also lets it have default values for 'missing' columns, so it can always generate row data with the correct number of fields.
There is a distressingly high amount of PHP which uses the submitted field names to build the SQL rather than starting with a known list of field names. In my experience, programmers do this because they are in control of the generated form, but forget that they aren't really in control of the submitted form. All it takes is a little editing in FireBug and you can knock the page for six, potentially corrupting your database.
I'm not sure if this fits your situation exactly, but we use something similar to the following for handling queries with data we aren't sure we have absolute control over. The form input names match the column names so if your's don't, you'll need to come up with the correct mapping.
This retrieves the column data from the table, and then builds the query from the form data using only the elements that match columns that exist in the table.
DB() is our wrapper around MDB2.
$db = new DB();
$sql = 'DESCRIBE `table`';
$result = $db->query($sql);
$row = array();
$query = array();
while ($row = $result->fetchRow())
{
if (array_key_exists($row['field'], $form_data))
if (is_null($form_data[$row['field']]))
$query[$row['field']] = 'NULL';
else
$query[$row['field']] = $db->quote($form_data[$row['field']]);
}
$keys = array_keys($query);
foreach ($keys as &$key)
$key = $db->quoteIdentifier($key);
unset($key);
$vals = array_values($query);
$sql = 'INSERT INTO `table` '
. '(' . implode(', ', $keys) . ') '
. 'VALUES(' . implode(', ', $vals) . ')';