I have looked at other posts and tried some of the suggestions but I still can't seem to populate a specific table in my database.
I will supply some blocks of my code to put things into perspective.
Here is my code for creating the table I want to populate with data:
CREATE TABLE `Devices` (
`dID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`deviceType` enum('BT','C1','AW') DEFAULT NULL COMMENT 'BT = Bluetooth, C1 = C1 Reader, AW = Acyclica Wifi',
`deviceName` varchar(255) NOT NULL DEFAULT '',
`deviceIP` varchar(15) NOT NULL DEFAULT '',
`devicePort1` int(4) NOT NULL,
`devicePort2` int(4) DEFAULT NULL,
`deviceRealLatitude` float(10,6) NOT NULL,
`deviceRealLongitude` float(10,6) NOT NULL,
`deviceVirtualLatitude` float(10,6) DEFAULT NULL,
`deviceVirtualLongitude` float(10,6) DEFAULT NULL,
`deviceChanged` tinyint(1) DEFAULT NULL,
`deviceStatus` tinyint(1) DEFAULT NULL,
`deviceLastSeen` timestamp NULL DEFAULT NULL,
`deviceBufferSize` int(4) DEFAULT NULL,
`deviceSoftwareVersion` varchar(20) DEFAULT NULL,
`deviceMacAddress` varchar(17) DEFAULT NULL,
`deviceTest` tinyint(1) DEFAULT NULL,
`deviceAPIKey` varchar(100) DEFAULT NULL COMMENT 'Only used with the Acyclia Scanners',
`deviceSerialID` int(6) DEFAULT NULL COMMENT 'Only used with the Acyclia Scanners',
PRIMARY KEY (`dID`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
I have declared all the field variables i.e
$dID = 0;
.....
$deviceSerialID = 0;
I checked if each field is set i.e
isset($_POST['dID']) == 1 ? ($dID = ($_POST['dID'])) : null;
.....
isset($_POST['deviceSerialID']) == 1 ? ($deviceSerialID = ($_POST['deviceSerialID'])) : null;
Here is where I use INSERT INTO "table name" --> VALUES
$insert_query = "INSERT INTO Devices (`dID`, `deviceType`, `DeviceName`, `deviceIP`,
`devicePort1`, `devicePort2`, `deviceRealLatitude`, `deviceRealLongitude`,
`deviceVirtualLatitude`, `deviceVirtualLongitude`, `deviceChanged`, `deviceStatus`,
`deviceLastSeen`, `deviceBufferSize`, `deviceSoftwareVersion`, `deviceMacAddress`,
`deviceTest`, `deviceAPIKey`, `deviceSerialID`) VALUES ('".$dID."', '".$deviceType."',
'".$deviceName."', '".$deviceIP."', '".$devicePort1."', '".$devicePort2."',
'".$deviceRealLatitude."', '".$deviceRealLongitude."', '".$deviceVirtualLatitude."',
'".$deviceVirtualLongitude."', '".$deviceChanged."', '".$deviceStatus."',
'".$deviceLastSeen."', '".$deviceBufferSize."', '".$deviceSoftwareVersion."',
'".$deviceMacAddress."', '".$deviceTest."', '".$deviceAPIKey."',
'".$deviceSerialID."')";
mysqli_query($conn,$insert_query);
Now, in my html form, I only want to input data for some of the fields:
<fieldset>
<form name = "form1" id = "form1" action = "" method = "post">
Device ID: <input type="text" name="dID" > <br>
Device Type: <select name="deviceType">
<option value = "BT">BT</option>
<option value = "C1">C1</option>
<option value = "AW">AW</option>
</select> <br>
Device Name: <input type="text" name="deviceName" > <br>
Device IP: <input type="text" name="deviceIP" > <br>
Device Port 1: <input type="text" name="devicePort1"> <br>
Device Port 2: <input type="text" name="devicePort2"> <br>
<input type = "submit" name = "submit" value = "submit" />
</fieldset>
</form>
I get no errors when I enter my data and hit submit. I realize that some of the things I have done in the code are not necessary such as the tick marks. Its all been a matter of trying to see if it would fix my problem. Any suggestions as to what I can do please?
UPDATE 6/20/14
It seems that trouble lies in my CREATE TABLE syntax. When I replace type 'int' or 'float' with 'varchar', for the fields (dID is an exception), it updates the table. Anyone familiar with posting an 'int' or 'float' value?
UPDATE 6/20/14 A couple hours later...
Guys, it seems I have discovered the problem. It was a small technical issue and I complicated the code to drown in further error.
The idea follows this:
I do not need to worry about a field being set at this point, as many fields will remain null. I only need to fill a few out using this method for each field:
i.e
$deviceType = $_POST['deviceType'];
Also, the using an 'int' or 'float' requires a difference in how to implement the INSERT INTO ... VALUES clause. If leaving it null (which I am for now), I cannot do this:
$insert_query1 = "INSERT INTO Devices (deviceChanged) VALUES ('$deviceChanged');
This iteration was preventing the table from being filled with its appropriate values.
Instead, fill it with null:
$insert_query1 = "INSERT INTO Devices (deviceChanged) VALUES (NULL);
PHP now inserts data into MySQL. Thanks for the help!
isset return boolean value (true/false) not integer or something else (http://www.php.net//manual/en/function.isset.php)
And another mistake is about how you use ternary comparision. See more about that here: http://davidwalsh.name/php-shorthand-if-else-ternary-operators
So instead of:
isset($_POST['deviceName']) == 1 ? ($deviceName = ($_POST['deviceName'])) : null;
you should write
$deviceName = isset($_POST['deviceName']) ? $_POST['deviceName'] : null;
Also please consider using some sort of loop to assign these variables (if they are at all needed) and not duplicate your code in huge amounts.
You are trying to insert a string in a place of a float.
You should remove the ticks from the non varchar columents. example devicePort1 is declared and int but the insert statement is sending a value with a tick like this , '".$devicePort1."', instead of this, because MySQL expects an int u should send the , ".$devicePort1.", , i.e with out the ticks.
Also because ID is AUTO_INCREMENT You should not to try to set value to it. To check if your statement is correct echo $query , then try to execute that from MySQL console or PHPMyAdmin.
A good practice is to use prepared statements or PDO. check this PHP: PDO - Manual or Prepared Statements Manual. Those links are from Php.net and they contain a very good explanation with examples;
Related
so, i'm trying to show a certain value in a table row, if the value recieved by post is null.
So far i've got this as my small database (it's in spanish):
DROP DATABASE IF EXISTS fantasmas;
CREATE DATABASE fantasmas;
USE fantasmas;
CREATE TABLE tipos(
ID tinyint(2) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
TIPO VARCHAR(45) UNIQUE
);
CREATE TABLE datos(
ID tinyint(2) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
NOMBRE VARCHAR(50) NOT NULL,
ARCHIVO VARCHAR(30),
AVISTAMIENTO VARCHAR(50) NOT NULL,
LOCALIDAD VARCHAR(50) NOT NULL,
INFO VARCHAR(200),
FKTIPOS TINYINT(2) UNSIGNED,
FOREIGN KEY (FKTIPOS) REFERENCES tipos(ID)
);
INSERT INTO tipos (TIPO) VALUES('Vapor'), ('Forma Animal'), ('Forma Humanoide'), ('Dios/Semidios'),('No Catalogado');
Those inserted values into "tipos" are then showed in options like this:
<select name="tipos">
<option value="sintipo">---------</option>
<?php
while( $row = mysqli_fetch_assoc($rta)):
$tipo = $row['TIPO'];
echo '<option value="'.$row['ID'].'">'.$tipo.'</option>';
endwhile;
?>
</select>
After, when the form is sent, the inset to the table, looks like this, it assigns null value if someone select the "------" option:
$query = "INSERT INTO datos SET NOMBRE='$nombre', AVISTAMIENTO='$lugar', LOCALIDAD='$localidad', INFO='$info', ARCHIVO='$ruta', FKTIPOS = NULLIF('$tipo','sintipo')";
All the data filled in the form, is then showed in a different row of a table.
What I need now, is that, if someone selects the "------" option, the value shown in screen is "No catalogado"
So far I have not been able to do it.
Can anyone help me?
Before the insert happens you can do a null check on the PHP side. Or... you can just use SQL's built in ISNULL()
You can also use CASE statements in SQL to accomplish this behavior across multiple values.
I know this isn't the most lengthy answer, but it should work.
Is this what your asking for?
$query = "INSERT INTO datos SET NOMBRE='$nombre', AVISTAMIENTO='$lugar', LOCALIDAD='$localidad', INFO='$info', ARCHIVO='$ruta', FKTIPOS = " . ($tipo == 'sintipo' ? 'NULL' : "'$tipo'");
Be aware that you have very dirty code, you don't even filter and escape income values, as I guess. Try to google php mysql escape values.
This question already has answers here:
Insert NULL instead of empty string with PDO
(3 answers)
Closed last month.
I searched any possible help that can be found online but still the problem with INSERT NULL using PHP PDO persists.
The script is a csvupload script originally came from here Import CSV into MySQL
To make the story short, Let me present the possible cause..
if($linearray[4]=='Unknown')
$linearray[4]=null;
$linemysql = implode("','",$linearray);
$linemysql = "'".$linemysql."'";
$setsu->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$tsuika = $setsu->prepare("INSERT INTO tablename (SubAgentID, BookID, AgentID, SubAgentName, Risk, Area, CurrentBalance) VALUES ($linemysql)");
$tsuika -> bindValue(':Risk', null, PDO::PARAM_INT);
$tsuika ->execute();
Looking the code above, I explicitly set the field values on the prepare statment.
On phpmyadmin the Risk field accepts NULL, set the default value to NULL, and has no problems. But when doing INSERT with PHP the value it gets is 0. Why?
Before Inserting, I echoed it and if the field $linearray[4] contains Unknown, it converts it to NULL yielding, '' for that part.
table structure
CREATE TABLE IF NOT EXISTS `subagentdb` (
`SubAgentID` int(10) NOT NULL AUTO_INCREMENT,
`BookID` int(10) NOT NULL,
`AgentID` int(10) NOT NULL,
`SubAgentName` varchar(30) NOT NULL,
`Risk` float DEFAULT NULL,
`Area` varchar(20) NOT NULL,
`CurrentBalance` float NOT NULL,
PRIMARY KEY (`SubAgentID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
You're binding the value explicitly as PDO::PARAM_INT. Whatever value you pass will be cast to an int because of that. null casts to 0.
To actually bind an SQL NULL value, you need to bind the value as PDO::PARAM_NULL.
just use PDO::PARAM_NULL instead of PDO::PARAM_INT ? I think the NULL is converted to 0 (INT) instead of null value
If you back-up a and then restore the table, the null value becomes 0. The only way I found to correct this is after the create table, add "UPDATE table SET foo to null WHERE foo = 0".
I have problem with dynamiccaly adding form fields in CakePHP app and I don't know how to solve it. I want to have form in EventsController/add.ctp for add Event where I want to have fields Events.name, Dates.from, Dates.to, Dates.endregister, Dates.location_id, {optional more Dates.from, Dates.to, ...}, Terms_mem.teacher_id {and optional more Terms_mem.teacher_id} My tables are:
CREATE TABLE `events` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(150) NOT NULL
);
CREATE TABLE `dates` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`from` datetime NOT NULL,
`to` datetime NOT NULL,
`endregister` datetime,
`event_id` int(11) NOT NULL,
`location_id` int(11) NOT NULL,
FOREIGN KEY (`event_id`) REFERENCES `events`(`id`),
FOREIGN KEY (`location_id`) REFERENCES `locations`(`id`)
);
CREATE TABLE `locations` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`street` varchar(70),
`city` varchar(70) NOT NULL
);
CREATE TABLE `dates_mem` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`teacher_id` int(11) NOT NULL,
`date_id` int(11) NOT NULL,
FOREIGN KEY (`teacher_id`) REFERENCES `users`(`id`),
FOREIGN KEY (`date_id`) REFERENCES `dates`(`id`)
)
So form would look like:
<?php echo $this->Form->create('Event'); ?>
<fieldset>
<?php
// events
echo $this->Form->input('name');
// dates
echo $this->Form->input('from');
echo $this->Form->input('to');
echo $this->Form->input('endregister');
echo $this->Form->input('location_id');
/* HERE optional dynamically add next inputs for dates (from, to, ...) */
// teachers
echo $this->Form->input('teacher_id');
/* HERE optional dynamically add next inputs for teachers(teacher_id) */
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
And after all that fields save to corresponding tables. Is this possible in CakePHP, version 2.4? If yes, could you help me with it?
EDIT:
burzum wrote:
$this->Form->input('Date.0.from');
$this->Form->input('Date.0.to');
$this->Form->input('Date.1.from');
$this->Form->input('Date.1.to');
Is it possible to do it as: ? Thus fields Date.1.from and Date.1.to add to form dynamically after click on button add next date
$this->Form->input('Date.0.from');
$this->Form->input('Date.0.to');
// button add next date
$this->Form->input('Date.1.from'); // after click on add next date
$this->Form->input('Date.1.to'); // after click on add next date
// button add next date
$this->Form->input('Date.2.from'); // after click on add next date
$this->Form->input('Date.2.to'); // after click on add next date
// button add next date
Have you tried to read the manual? If not read the manual it is explained there in detail in the section "Saving your data". See this part.
In short, first the view
$this->Form->input('FirstModel.field1');
$this->Form->input('SecondModel.field1');
$this->Form->input('SecondModel.field2');
$this->Form->input('Date.0.from');
$this->Form->input('Date.0.to');
$this->Form->input('Date.1.from');
$this->Form->input('Date.1.to');
// ...
Controller:
$this->saveAll($this->request->data);
Yes, you can add fields dynamically on the fly, use Javascript to inject additional fields into the DOM. Either via a JS template or via AJAX. Just make sure the form inputs you generate follow the CakePHP conventions and that you white list the JS generated fields. Also make sure you validate the inputs you've white listed very strict to avoid getting things added you don't want. You should use the security component if you don't use it already.
I want to be able to create dynamic tables, for custom user surveys... like survey monkey... how would I go about create something like that?
Because I want to give the ability to the user to create the survey, with different amount of text fields, and different a option fields... I would need to create a custom table for each survey.
Would something like this be possible?
<?php
$table_name = 'survey_'.$_POST['surveyid'];
$query = 'CREATE TABLE ? (
`responseid` INT NOT NULL AUTO_INCREMENT,
`textarea1` TEXT NULL,
`textarea2` TEXT NULL,
`textarea3` VARCHAR(255) NULL,
`drop_down1` VARCHAR(255) NULL,
`drop_down2` VARCHAR(255) NULL,
`bool1` BIT NULL,
`bool2` BIT NULL,
PRIMARY KEY (`responseid`))';
if($stmt = $mysqli->prepare($query)){
$stmt->bind_param('s', $table_name);
$stmt->execute();
$stmt->close();
}else die("Failed to prepare");
?>
The above example comes back with "Failed to prepare", because I don't think I can prepare a table name... is there another work around using mysqli?
if(ctype_digit($_POST['surveyid']) && $_POST['surveyid']>0){
$table_name = 'survey_'.$_POST['surveyid'];
$query = 'CREATE TABLE '.$table_name.' (
`responseid` INT NOT NULL AUTO_INCREMENT,
`textarea1` TEXT NULL,
`textarea2` TEXT NULL,
`textarea3` VARCHAR(255) NULL,
`drop_down1` VARCHAR(255) NULL,
`drop_down2` VARCHAR(255) NULL,
`bool1` BIT NULL,
`bool2` BIT NULL,
PRIMARY KEY (`responseid`))';
I know I can just try to sanitize the $_POST['surveyid'] (like I did above) but I prefer to prepare it if possible.
$table_name = 'survey_'.$_POST['surveyid'];
Do not do the above. It is easy for a hacker to exploit your site if you include $_GET or $_POST data directly in any SQL string.
But you can't use parameters for a table name. A parameter takes the place of a single scalar value only. You can prepare CREATE TABLE but you can't use parameters for identifiers (e.g. table names).
The best practice is to make sure your table name conforms to a rule, for example only the leading portion of a string of numeric digits, up to the maximum length of a MySQL table name:
$table_name = 'survey_' . strspn(trim($_POST['surveyid']), '0123456789', 0, 56);
If you have other rules for a surveyid, then you could use preg_replace():
$table_name = 'survey_' . preg_replace('^(\w+)', '$1', trim($_POST['surveyid']));
It is not possible to prepare a data definition language statement like "CREATE TABLE". I can't find the reference in the MySQL docs that explains this, but I did find a good explanation on the PHP documentation site.
I am trying to dynamically insert 'NULL' into the database using PDO.
TABLE STRUCTURE:
CREATE TABLE IF NOT EXISTS `Fixes` (
`Id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'PK',
`CurrencyId` int(11) NOT NULL COMMENT 'FK',
`MetalId` int(11) NOT NULL COMMENT 'FK',
`FixAM` decimal(10,5) NOT NULL,
`FixPM` decimal(10,5) DEFAULT NULL,
`TimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`Id`),
KEY `CurrencyId` (`CurrencyId`),
KEY `MetalId` (`MetalId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=13 ;
PHP / PDO QUERY:
$sql = 'UPDATE
Fixes
SET
FixAM = :fixAM,
FixPM = :fixPM
WHERE
MetalId IN (SELECT Id FROM Metals WHERE Name = :metal) AND
CurrencyId IN (SELECT Id FROM Currencies Where Id = :currency)';
$stmt = $db->prepare($sql);
for ($i = 0; $i<3; $i++) {
$stmt->execute(array(
':metal' => 'Silver',
':fixAM' => $fix['FixAM'][$i],
':fixPM' => $fix['FixPM'][$i],
':currency' => ($i+1))
);
}
e.g. sometimes, the value for $fix['FixPM'][$i] is sometimes 'NULL'. How do I insert this into the database? When I run the query and then view the data in the database, this record shows 0.0000, and not null.
How do I insert NULL values using PDO? provides a few solutions.
I dont think I can use $stmt->execute(array( ':v1' => null, ':v2' => ... )) as per example because sometimes the item is null, and sometimes not. As such, I need to refer to the variable I have created $fix['FixPM'][$i] and make that null as and when needed
Thanks in advance.
This appears to me to be a(n unreported?) bug in PDO's prepared statement emulation:
the implementation of PDOStatement::execute() eventually invokes pdo_parse_params();
that, in turn, attempts to quote/escape values based on the relevant parameter's data type (as indicated by the $data_type arguments to PDOStatement::bindValue() and PDOStatement::bindParam()—all parameters provided as $input_parameters to PDOStatement::execute() are treated as PDO::PARAM_STR, as stated in the documentation of that function);
string-typed values are escaped/quoted by calling the relevant database driver's quoter() method irrespective of whether they are null: in the case of PDO_MySQL, that's mysql_handle_quoter(), which (eventually) passes the value to either mysqlnd_cset_escape_quotes() or mysql_cset_escape_slashes(), depending on the server's NO_BACKSLASH_ESCAPES SQL mode;
given a null argument, both of those functions return an empty string.
My opinion is that, prior to switching on the parameter's type (in step 2 above), pdo_parse_params() should set the type to PDO::PARAM_NULL if the value is null. However, some might argue that this would prevent type-specific handling of null values where appropriate, in which case the string case (in step 3 above) should definitely handle null values before proceeding with a call to the driver's quoter() method.
As an interim workaround, disabling prepared statement emulation is usually for the best anyway:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);