PHP + PDO, my escaped characters won't show when displayed - php

First, I'd like to apologize, I'm still a beginner.
For learning purposes I'm creating a blog engine and I just noticed that when I list the comments, escaped characters like carriage return (pressing enter) are shown in the database correctly, but only a whitespace character when displaying the comments.
I'm using PostgreSQL 8.3.
Here you can see an example database entry:
fema=> select * from comments where id = 54;
-[ RECORD 1 ]-------------------------
id | 54
authorid | 1
text | This new line won't show.\r
: No\r
: \r
: new\r
: \r
: \r
: \r
: lines.
time | 1341417673
postid | 15
answerid | 0
Here you can see what var_dump() shows:
string(50) "This new line won't show. No new lines."
This is how I'm getting the data:
$stmt = db::$db->prepare("select comments.id as commentid ,authorid,text,time,postid,answerid,users.* from comments left join users on users.id = comments.authorId where postid = :postId");
$stmt->execute(array('postId' => $_GET['p']));
$commentRslt = $stmt->fetchAll();
Then foreach to iterate through them and replace the mark I'm using to identify things I have to replace:
$currComment = str_replace('{{{cms:comment:text}}}', $commentRslt[$key]['text'], $currComment);
This is how I insert the new comment to the DB:
$stmt = self::$db->prepare('INSERT INTO comments (authorId, text, time, postId, answerId) VALUES (:authorId, :text, :time, :postId, :answerId)');
$stmt->execute(array( 'authorId' => $_SESSION['userId'],
'text' => str_replace(array('<','>'), array('&lt','&gt'), isset($_POST['newCommentArea']) ? $_POST['newCommentArea'] : $_SESSION['newCommentArea']),
'time' => time(),
'postId' => isset($_POST['commentNew']) ? $_POST['commentNew' ] : $_SESSION['postId'],
'answerId' => $answerId));
Sorry for the many code samples, but I don't even know where the problem is and I wanted to be thorough.
So could anyone please tell me how to solve the problem? If only just by telling me where I made the mistake. I really have no clue.
Thanks.

Jut guessing here, but:
Consecutive whitespace is collapsed to a single space by HTML/the browser. Replace newlines with <br> tags if you want to keep them, using nl2br.

Related

filter data with php or sql?

I'm not sure if this is an anti-pattern or not, but it feels a bit convoluted, so I'd like to get your opinion on how these cases should be handled:
Let's say we have this data:
$sofas[0]['color'] = 'green';
$sofas[0]['pillows'] = 8;
$sofas[0]['pattern'] = 'moons';
$sofas[1]['color'] = 'green';
$sofas[1]['pillows'] = 8;
$sofas[1]['pattern'] = 'ducks';
$sofas[1]['footrest'] = 'small';
$sofas[2]['color'] = 'green';
$sofas[2]['pillows'] = 8;
$sofas[2]['pattern'] = 'stripes';
$sofas[2]['speakers'] = 'badass';
color, pillows and pattern comes from the database, whilst "footrest" and "speakers" have been added on by an api.
We can say for the sake of argument that there are 1250 different attributes that can be added by the api like "footrest" and "speakers".
We now want to load an some data from the database based on these attributes, like an image for example.
So we have a table that looks like this:
ID , attribute_value, image
1 , 'color_green' 'img0023',
2 , 'pillows_8' 'img003',
3 , 'pattern_moons' 'img002',
6 , 'pattern_ducks' 'img0083',
7 , 'footrest_small' 'img0058',
10 , 'pattern_stripes''img0073',
11 , 'speakers_badass''img00pluto'
etc , etc , etc;
So, the way I figure I can approach this two ways:
$sofaSQL="'color_green',
'pillows_8',
'pattern_moons',
'pattern_ducks',
'footrest_small',
'pattern_stripes',
'speakers_badass'";
$sql = "SELECT ID, attribute_value, image
FROM `example`
WHERE attribute_value IN ($sofaSQL)"
and then loop through the array and check if the key + '_' + value matches the rows in the recordset to see what images should be used for sofas[0], sofas[1] and sofas[2].
The other option I see would be to prep each sofa with a different sql statement, ie:
$sofaSQL="'color_green',
'pillows_8',
'pattern_moons';
-add images-
$sofaSQL="'color_green',
'pillows_8',
'pattern_ducks',
'footrest_small';
-add images-
$sofaSQL="'color_green',
'pillows_8',
'pattern_stripes',
'speakers_badass'";
-add images-
That seems simpler, but it doesn't feel right to hammer the database with a seperate request for each item in the array.
So, what would you recommend in this case? IS there a better way of dealing with attributes that are selected randomly/from an api?

I'm stuck with this logic proble.m

WHAT I HAVE:
-I have a file with various products ( Flag "P" mean reserved, without "P" mean sold but not reserved)
ELEMENTS
PRODOTTO Quantita Terminale
TAMOXIFENE EG*20CPR RIV 20MG 00002n 04
FERRITIN COMPLEX*OS 10FL 8ML 00001 P 01
VOLTADOL*10CER MEDIC 140MG 00001n 05
LEDERFOLIN*10CPR 7,5MG 00002 P 03
-From this file,through a regular php expression (that search only strings with "P" flag), I extract products and insert it into mysql db.
insericineldb.php
$txt = file_get_contents('./FILE', true);
$specialChars = preg_quote( '#$%^&*()+=-[]\';,./{}|\":<>?~', '#' );
preg_match_all('#([0-9]{4,9}\s+[A-Z]{1}\s+([' . $specialChars . 'A-Z0-9 ]+)\s+([0-9]{3,7})n?\s+P\s+([0-9]+))#', $txt, $match);
$products = [];
foreach (array_keys($match[2]) as $idx) {
$tagliaprodotto = rtrim(substr($match[2][$idx],1));
$tagliaquantita = ltrim($match[3][$idx],'0');
$products[] = [
'prodotto' => $tagliaprodotto,
'quantita' => $tagliaquantita,
'terminale' => $match[4][$idx]
];
}
$query = $pdo->prepare('INSERT INTO tabella (prodotto, quantita, terminale, data) VALUES (:prodotto, :quantita, :terminale, NOW()) ON DUPLICATE KEY UPDATE quantita = VALUES(quantita), terminale = VALUES(terminale)');
foreach ($products as $product) {
$query->execute($product);
}
-I extract products automatically thanks to the use of a batch (which monitors the variation of the file).
BATCH
#echo off
:loop
timeout -t 1 >nul
for %%i in (c:\file) do echo %%~ai|find "a">nul || goto :loop
"c:\xampp\php\php.exe" -f c:\xampp\htdocs\inseriscineldb.php
rem do workload
attrib -a c:\file
goto :loop
The file:
-At a certain time NOT REGULAR (when they make the final order, 2 times a day) is emptied NOT COMPLETELY (some strings with and without "P" remain in the file but they aren't important, are important only for logic because I can't use an if as: when P=0 don't start the query).
-Furthermore sometimes some products (ES. FERRITIN COMPLEX*OS 10FL 8ML 00001 P 01) is eliminated VOLUNTARILY (Suppose a customer wants a 50-milliliter product, i reserve it but after he wants a 8-milliliter product, the old 50 milliliters order will not be deleted from the database)
PROBLEM:
1)So if I enter products into the database through INSERT INTO when one of the elements is removed voluntarily, it isn't removed from the database.
2)However, if I use REPLACE instead of INSERT, when the file is emptied, the other elements inside the database will also be deleted and now I'm stuck.
A way to to this in a pretty simple manner, is to read all the elements from the Database ( with a "select * from tabella) then check which one is present into the file and delete / insert / update what you need.

Removing particular string with special character and number

I have following example its working fine but i want to remove Issue No1 – ,Issue No2 – ,Issue No3..... at once because I don't want to add Issue No2 – , Issue No3 ... everytime in preg_replace. I think this is possible with preg_replace. I wrote following code but did not get the actual result. Any advise or guidance would be greatly appreciated.
$catName="Issue No1 – This is new Issue No2 – This is also new item Issue No3 – This is new one There are 1 2 3 items ....... ";
echo $catName= preg_replace("/Issue No\d+/","",$catName);
Output should be:
This is new This is also new item This is new one There are 1 2 3 items .......
You also have to add - at end of your expression
preg_replace("/Issue No\d+ –/", "", $catName);
DEMO
Try like below -
$catName = preg_replace("(Issue No[0-9]+)", "", $catName);
<?php
$catName="Issue No1 - This is new Issue No2 - This is also new item Issue No3 - This is new one There are 1 2 3 items ....... ";
echo "<h1>$catName</h1>\n";
$catName = preg_replace("/Issue No\d+ - /","",$catName);
echo "<h1>$catName</h1>\n";
?>

Get data with spaces from Google Spreadsheets (via PHP)

How I can get data from my Google Spreadsheet if it contains spaces?
Example: I have two columns: Person1 and Person2 and I need find a match names.
I read this Google API How to connect to receive values from spreadsheet
And tried:
$listFeed = $worksheet->getListFeed(array("sq" => "person1" . " = " . "Jon Doe"));
and it's not working. I also tried 'Jon%20Doe' but it's still not working. For rows without spaces in this field it works.
The expression "person1" . " = " . "Jon Doe" that you assign to the sq key in your array results in a "person1 = Jon Doe" string. Here it is likely that Jon Doe isn't seen as a string of its own, as you would like it to be.
Maybe you could try to quote Jon Doe like this:
$listFeed = $worksheet->getListFeed(array("sq" => "person1 = 'Jon Doe'"));
Or like this:
$listFeed = $worksheet->getListFeed(array("sq" => 'person1 = "Jon Doe"'));
Also, make sure the column parameter in your query string (here person1) is consistent with your column name (Person1). Case mismatch might be why it fails.

MSSQL + PHP - Error to insert oriental char

I'm having a problem to insert a oriental character with bind variables in SQL Server.
i'm using MSSQL commands and PHP.
My PHP code is like this:
$sql = "
CREATE TABLE table_test
( id int
,nvarchar_latin nvarchar(255) collate sql_latin1_general_cp1_ci_as
);";
$stmt = mssql_query($sql);
$conn = mssql_connect("server","user","pass");
mssql_select_db('test')
$stmt = mssql_init('test..sp_chinese', $conn);
$id = 1;
$nvarchar_latin = '重建議';
mssql_bind($stmt, '#id' , $id , SQLINT1);
mssql_bind($stmt, #nvarchar_latin, $nvarchar_latin, SQLVARCHAR);
mssql_execute($stmt);
My procedure is like this:
ALTER PROCEDURE sp_chinese
#id int
,#nvarchar_latin nvarchar (255)
AS
BEGIN
INSERT INTO char_chines (id, nvarchar_latin)
VALUES (#id, #nvarchar_latin);
END
this work if I change the oriental characters for normal one.
if I run directly this insert, it work's fine:
INSERT INTO table_test (id, nvarchar_latin)
VALUES (1, '重建議');
So, cleary the problem is when I send the variable from PHP to SQL Server.
Anyone have a clue how to make this works? some casting or something?
Thanks!
A solution that uses just the PHP (or even JavaScript) is to convert the character to its HEX value and store that. I don't know if you want to go this route but and I don't have time to show you the code but here is the full theory:
A non-English character is detected, like so: 重
Convert to HEX value (Look here for starters. But a search for Javascript will help you find better ways to do this even in PHP): 14af
NOTE: That is not what 重 really is in HEX
Store in a way that you can convert back to its original value. For example how can you tell what this is: 0d3114af is it 0d - 31 - 14 - af OR is it 0d31 - 14af. You can use deliminators like | or a . but one way is to provide padding of 00 in front. An English character would be only 2 characters long like 31 or af non-English will be 4 like 14af. Knowing this you can just split every 4 characters and convert to their values.
Downside is you will need to change your Database to accommodate these changes.
[ UPDATE ] -----
Here is some JavaScript code to send you off in the right direction. This is completely possible to replicate in PHP. This does not search for characters though, its part of an encryption program so all it cares about is turning everything into HEX. English characters will be padded with 00 (This is my own code hence no link to source):
function toHex(data) {
var result = '';
// Loop through entire string of data character by character
for(var i=0;i<data.length;i++) {
// Convert UTF-16 Character to HEX, if it is a 2 chracter HEX add 00 padding in front
result += (data.charCodeAt(i) + 0x10000).toString(16).slice(1);
}
// Display the result for testing purposes
document.getElementById('two').value = result;
}
function fromHex(data) {
var result = '', block = '', pattern = /(00)/; // Pattern is the padding
for(var i=0;i<data.length;i = i+4) {
// Split into separate HEX blocks
block = data.substring(i,i+4);
// Remove 00 from a HEX block that was only 2 characters long
if(pattern.test(block)){
block = block.substring(2,4);
}
// HEX to UTF-16 Character
result += String.fromCharCode(parseInt(block,16));
}
// Display the result for testing purposes
document.getElementById('two').value = result;
}

Categories