I've got some simple updates inside my migration with strings that may contain special characters. For example:
$this->execute("UPDATE `setting` SET `classname` = 'org\foo\Bar' WHERE `id` = 1 ");
The problem with this for example, org\foo\Bar when inserted into MySQL treats \ as escape characters. For each DB phinx supports, I'm sure there are special characters that need to be handled in strings that when using PDO directly you'd get around by using prepared statements and binding parameters.
Is there any native way in phinx to escape strings or do I need to fall back on something like PDO::quote()?
As alluded to in Charlotte's OP comments, it doesn't look like this feature exists. The work around is the following:
Grab the the PDO connection
Use the quote() or manually construct a query using the connection directly
Here's my code example using quote()
public function change()
{
$conn = $this->getAdapter()->getConnection();
$quotedString = $conn->quote('org\foo\Bar');
$this->execute("UPDATE `setting` SET `classname` = $quotedString WHERE `id` = 1 ");
}
Related
What is the best way to escape unwanted characters in order to avoid further database syntax errors when executing insert/update queries when submitting forms?
eg. $note = $this->db->escape( $data['note'] );
INSERT query renders a further syntax error.
ie.
$this->db->query("INSERT INTO notes (note_id, note) VALUES ('$note_id','$note')");
as it mentioned in Codeignitier documentation when using query builder class
All values are escaped automatically producing safer queries.
so its safer to use query builder class for both error handling and security
Escaping Queries
It’s a very good security practice to escape your data before submitting it into your database. CodeIgniter has three methods that help you do this:
$this->db->escape() This function determines the data type so that it can escape only string data. It also automatically adds single quotes around the data so you don’t have to:
$sql = "INSERT INTO table (title) VALUES(".$this->db->escape($title).")";
$this->db->escape_str() This function escapes the data passed to it, regardless of type. Most of the time you’ll use the above function rather than this one. Use the function like this:
$sql = "INSERT INTO table (title) VALUES('".$this->db->escape_str($title)."')";
$this->db->escape_like_str() This method should be used when strings are to be used in LIKE conditions so that LIKE wildcards (‘%’, ‘_’) in the string are also properly escaped.
$search = '20% raise';
$sql = "SELECT id FROM table WHERE column LIKE '%" .
$this->db->escape_like_str($search)."%' ESCAPE '!'";
Note:
The escape_like_str() method uses ‘!’ (exclamation mark) to escape special characters for LIKE conditions. Because this method escapes partial strings that you would wrap in quotes yourself, it cannot automatically add the ESCAPE '!' the condition for you, and so you’ll have to manually do that.
I am currently updating a section of code that uses mysql currently the escape string is structured like this: $product_name = mysql_real_escape_string(trim($_POST['product_name'])); and works fine.
My issue is when I change the above string to $product_name = mysqli_real_escape_string($database, (trim($_POST['product_name']))); and declare the following: $database = $this->load->database(); above it I get the error that its NULL
How do I escape a string with CI?
CodeIgniter user manual wrote the following.
Beyond simplicity, a major benefit to using the Active Record features is that it allows you >to create database independent applications, since the query syntax is generated by each >database adapter. It also allows for safer queries, since the values are escaped >automatically by the system.
You can use Input class in your controller.
$this->load->model('mymodel');
$something = $this->input->post('something');
$results = $this->mymodel->mymethod($something);
In your model
$this->db->insert('mytable', $data);
You use
$this->db->query("select ?",array("value"));
Where each ? In thee select is the variable you want escaped
I am trying to execute this query using PDO:
select * from users where uuid = 0x1e8ef774581c102cbcfef1ab81872213;
I pass this SQL query to the prepare method of PDO:
select * from users where uuid = :uuid
Then I pass this hashmap to execute:
Array ( [:uuid] => 0x1e8ef774581c102cbcfef1ab81872213 )
It looks like this query is being executed on the mysql server, when I call fetchAll:
select * from users where uuid = '0x1e8ef774581c102cbcfef1ab81872213';
How can I execute the query without having PDO add the quotes around my hex?
Thanks,
Steve
Your value HAS to be inserted as a string, as it's far beyond (128bit) what can be represented as a normal number in PHP in both 64bit and 32bit editions.
e.g. skip the placeholders and embed it into the query string directly:
$uuid = '0x....';
$sql = "SELECT ... WHERE uuid = $uuid";
which means you lose the benefits of placeholders, and will have to deal with SQL injection mitigation directly.
You don't mention which DBMS you're using, but you might be able to get around it by exploiting your DBMS's casting functions, eg.
SELECT... WHERE uuid = CAST(:uuid AS uuid_type)
with this, even though it goes into the DB as a string, it'll be treated as a native uuid when push comes to shove.
This question already has an answer here:
json_encode problems with utf8 [closed]
(1 answer)
Closed 6 years ago.
I am writing to the database in the form of data from a form with jQuery json_encode.
However, data from the database will corrupt.
$db->query("SET NAMES utf8");
$kelime = array("Merhaba","Dünya");
$bilgi = json_encode($kelime);
$incelemeEkle = "
INSERT INTO incelemeRapor SET
bigData = '".$bilgi."'
";
$db->query($incelemeEkle);
Database Table Schema;
CREATE TABLE `incelemeRapor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bigData` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
MySQL Inserted Example Data;
["Merhaba","Du00fcnya"]
Always escape your data before puting it in a SQL query:
$incelemeEkle = "
INSERT INTO incelemeRapor SET
bigData = '".mysql_real_escape_string($bilgi)."'
";
(added mysql_real_escape_string() call)
json_encode() encodes non-ascii characters with the \u<code-point> notation; so json_encode(array("Merhaba","Dünya")); returns ["Merhaba","D\u00fcnya"].
Then this string is embeded in a SQL query:
INSERT INTO incelemeRapor SET
bigData = '["Merhaba","D\u00fcnya"]'
There is no special meaning for the escape sequence \u, so MySQL just removes the \; and this results in ["Merhaba","Du00fcnya"] being stored in database.
So if you escape the string, the query becomes:
$incelemeEkle = "
INSERT INTO incelemeRapor SET
bigData = '["Merhaba","D\\u00fcnya"]'
";
And ["Merhaba","D\u00fcnya"] is stored in the database.
I tried with mysql_real_escape_string() but not worked for me (result to empty field in database).
So I looked here : http://php.net/manual/fr/json.constants.php and the flag JSON_UNESCAPED_UNICODE worked for me fine :
$json_data = json_encode($data,JSON_UNESCAPED_UNICODE);
JSON_UNESCAPED_UNICODE is available only since PHP 5.4.0 !
So in addition to ensuring that your database is using utf8_unicode_ci, you also want to make sure PHP is using the proper encoding. Typically I run the following two commands at the top of any function which is going to potentially have foreign characters within them. Even better is to run it as one of the first commands when your app starts:
mb_language('uni');
mb_internal_encoding('UTF-8');
Those two lines have saved me a ton of headaches!
Like user576875 says, you just need to correctly treat your string before inserting it into the database. mysql_real_escape_string() is one way to do that. Prepared statements are another way. This will also save you from the SQL injection security issue that you might be susceptible to if you write user input directly into SQL. Always use one of the above two methods.
Also, note that this has little to do with UTF8. JSON is ASCII safe, so as long as you use an ASCII like character set (utf8, iso-8859-1), the data will be inserted and stored correctly.
I would apply BASE64 encoding to the JSON string. This should work with nearly every php setting, database, database version and setting:
$values = array("Test" => 1, "the" => 2, "West" => 3);
$encoded = base64_encode(json_encode($values));
$decoded = json_decode(base64_decode($encoded), true);
The following code is generating this
Warning: oci_execute() [function.oci-execute]:
ORA-00911: invalid character in F:\wamp\www\SEarch Engine\done.php on line 17
the code is...
<?php
include_once('config.php');
$db = oci_new_connect(ORAUSER,ORAPASS,"localhost/XE");
$url_name=$_POST['textfield'];
$keyword_name=$_POST['textarea'];
$cat_news=$_POST['checkbox'];
$cat_sports=$_POST['checkbox2'];
$anchor_text=$_POST['textfield2'];
$description=$_POST['textarea2'];
$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description)
VALUES( 9,".'{$url_name}'.",".'{$anchor_text}'.",".'{$description}'.")";
$result=oci_parse($db,$sql1);
oci_execute($result);
?>
Never insert user input directly into SQL. Use oci_bind_by_name() to prepare a secure statement. As a side effect, that will also fix the error you're getting (which is a quoting typo). The code would look like
$url_name = $_POST['textfield'];
$anchor_text = $_POST['textfield2'];
$description = $_POST['textfield3'];
$sql = 'INSERT INTO URL(Url_ID,Url_Name,Anchor_Text,Description) '.
'VALUES(9, :url, :anchor, :description)';
$compiled = oci_parse($db, $sql);
oci_bind_by_name($compiled, ':url', $url_name);
oci_bind_by_name($compiled, ':anchor', $anchor_text);
oci_bind_by_name($compiled, ':description', $description);
oci_execute($compiled);
You've got a few problems here. First, variables aren't interpolated into strings enclosed in single quotes. Try this simple script to see what I mean:
$a = 'hi';
print 'Value: $a'; // prints 'Value: $a'
vs.
$a = 'hi';
print "Value: $a"; // prints 'Value: hi'
Secondly, you'll need to escape the variables before using them to construct an SQL query. A single "'" character in any of the POST variables will break your query, giving you an invalid syntax error from Oracle.
Lastly, and perhaps most importantly, I hope this is just example code? You're using unfiltered user input to construct an SQL query which leaves you open to SQL injection attacks. Escaping the variables will at least prevent the worst kind of attacks, but you should still do some validation. Never use 'tainted' data to construct queries.
It's rather hard to say without seeing what the generated SQL looks like, what charset you are posting in and what charset the database is using.
Splicing unfiltered user content into an SQL statement and sending it to the DB is a recipe for disaster. While other DB APIs in PHP have an escape function, IIRC this is not available for Oracle - you should use data binding.
C.
It's because you have un-quoted quote characters in the query string. Try this instead:
$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description)
VALUES( 9,\".'{$url_name}'.\",\".'{$anchor_text}'.\",\".'{$description}'.\")";
You need single quotes around the varchar fields that you are inserting (which I presume are url_name, anchor_text, and description). The single quote that you currently have just make those values a String but in Oracle, varchar fields need to have single quotes around them. Try this:
$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) VALUES( 9,'".'{$url_name}'."','".'{$anchor_text}'."','".'{$description}'."')";
I don't have PHP anywhere to test it, but that should create the single quotes around your values.
Because really the sql you will eventually be executing on the database would look like this:
insert into URL
(
Url_ID,
Url_Name,
Anchor_Text,
Description
)
VALUES
(
9,
'My Name',
'My Text',
'My Description'
)
The main article Binding Variables in Oracle and PHP appears to be down but here is the Google Cache Version that goes into detail about how to bind variables in PHP. You definitely want to be doing this for 1) performance and 2) security from SQL injection.
Also, my PHP is a bit rusty but looks like you could also do your original query statement like this:
$sql1="insert into URL(Url_ID,Url_Name,Anchor_Text,Description) values ( 9, '$url_name', '$anchor_text', '$description')";
Edit
Also, you need to escape any single quotes that may be present in the data you receive from your form variables. In an Oracle sql string you need to convert single quotes to 2 single quotes to escape them. See the section here titled "How can I insert strings containing quotes?"
If you are still in starting developing, I want to suggest to use AdoDB instead of oci_ functions directly.
Your code above can be rewritten using AdoDB like this:
<?php
include_once('config.php');
$url_name=$_POST['textfield'];
$keyword_name=$_POST['textarea'];
$cat_news=$_POST['checkbox'];
$cat_sports=$_POST['checkbox2'];
$anchor_text=$_POST['textfield2'];
$description=$_POST['textarea2'];
//do db connection
$adodb =& ADONewConnection("oci8://ORAUSER:ORAPASS#127.0.0.1/XE");
if ( ! $adodb )
{
die("Cannot connect to database!");
}
//set mode
$adodb->SetFetchMode(ADODB_FETCH_BOTH);
//data for insert
$tablename = 'URL';
$data['Url_ID'] = 9;
$data['Url_Name'] = $url_name;
$data['Anchor_Text'] = $anchor_text;
$data['Description'] = $description;
$result = $adodb->AutoExecute($tablename, $data, 'INSERT');
if ( ! $result )
{
die($adodb->ErrorMsg());
return FALSE;
}
//reaching this line meaning that insert successful
In my code above, you just need to make an associative array, with the column name as key, and then assign the value for the correct column. Data sanitation is handled by AdoDB automatically, so you not have to do it manually for each column.
AdoDB is multi-database library, so you can change the databas enginge with a minimal code change in your application.