2010-02-21 175 views
7

PHP中是否有一個將引號添加到字符串的函數?帶引號的環繞字符串

"'".str."'"

這對於VARCHAR處理SQL查詢。我搜索了一下,沒有結果......

我做了以下內容:

$id = "NULL"; 
$company_name = $_POST['company_name'];   
$country = $_POST['country']; 
$chat_language = $_POST['chat_language']; 
$contact_firstname = $_POST['contact_firstname']; 
$contact_lastname = $_POST['contact_lastname']; 
$email = $_POST['email']; 
$tel_fix = $_POST['tel_fix']; 
$tel_mob = $_POST['tel_mob'];  
$address = $_POST['address'];  
$rating = $_POST['rating']; 

$company_name = "'".mysql_real_escape_string(stripslashes($company_name))."'"; 
$country = "'".mysql_real_escape_string(stripslashes($country))."'"; 
$chat_language = "'".mysql_real_escape_string(stripslashes($chat_language))."'"; 
$contact_firstname = "'".mysql_real_escape_string(stripslashes($contact_firstname))."'"; 
$contact_lastname = "'".mysql_real_escape_string(stripslashes($contact_lastname))."'"; 
$email = "'".mysql_real_escape_string(stripslashes($email))."'"; 
$tel_fix = "'".mysql_real_escape_string(stripslashes($tel_fix))."'"; 
$tel_mob = "'".mysql_real_escape_string(stripslashes($tel_mob))."'"; 
$address = "'".mysql_real_escape_string(stripslashes($address))."'"; 
$rating = mysql_real_escape_string(stripslashes($rating)); 

$array = array($id, $company_name, $country, $chat_language, $contact_firstname, 
$contact_lastname, $email, $tel_fix, $tel_mob, $address, $rating); 
$values = implode(", ", $array); 

$query = "insert into COMPANIES values(".$values.");"; 
+4

一般提示:一定要命名,你插入值,以每列,只有「插入到COMPANIES值中(「。$ values。」)「如果您更改了表的結構,或者將參數按錯誤順序排列,或者沒有提供足夠的參數,那麼您的查詢將會中斷。 – chelmertz 2010-02-21 01:11:18

+1

這是一個很好的PDO資源:http://www.kitebird.com/articles/php-pdo.html 。而且,我同意其中的其他帖子,準備好的陳述在所有方面都是一個提供查詢的高級方法。 – JAL 2010-02-21 02:14:40

+1

不檢查魔術引號gpc設置時不要使用'stripslashes()'。你可以很容易地把它包裝在一個自定義的'get_string()'函數中。 – BalusC 2010-02-21 04:32:31

回答

8

首先,我看你使用stripslashes()。這意味着你有magic quotes。我建議關閉它。

你可能想要做的是把一些這方面的功能:

function post($name, $string = true) { 
    $ret = mysql_real_escape_string(stripslashes($_POST[$name])); 
    return $string ? "'" . $ret . "'" : $ret; 
} 

然後:

$company_name = post('company_name'); 

這一切都不過是減少你有輕微的樣板量。

有些人建議使用PDO或mysqli來做這個事情,這樣你就可以使用預準備語句。雖然他們可以是有用的,但它肯定是而不是必要的。您正在逃避這些領域,因此聲稱存在SQL注入漏洞(至少在此代碼的情況下)是錯誤的。

最後,我不會這樣構造查詢。一方面,它依賴於公司表中的特定類型和順序的列。明確這一點要好得多。我通常這樣做:

$name = mysql_real_escape_string($_POST['name']); 
// etc 
$sql = <<<END 
INSERT INTO companies 
(name, country, chat_language) 
VALUES 
($name, $country, $language) 
END; 

這將足以完成任務。您當然可以使用mysqli或PDO進行調查,但這不是必需的。

+0

這不是說OP的代碼容易受到SQL注入的影響,而是SQL注入甚至不是準備好的語句參數的問題。 – outis 2010-02-21 04:32:51

+0

在插入'aValue,otherValue'時會出現一個小小的「未填充」字段問題,但它的工作原理是 – serhio 2010-02-21 12:20:25

4

創建您自己的。

function addQuotes($str){ 
    return "'$str'"; 
} 
+2

或者爲了使函數更好,還可以在其中添加mysql_real_escape_string。 – Marius 2010-02-21 01:42:51

2

不要這樣做。而是使用參數化查詢,例如PDO

+0

我是初學者,PDO很複雜。我如何在具體情況下使用PDO(我添加了一些代碼)?謝謝 – serhio 2010-02-21 00:42:07

+0

outis的答案進入了一個低層次的細節。 – 2010-02-21 00:45:14

9

不是直接將值插入到查詢中,而是使用prepared statements和參數,這些參數不易受SQL injection的影響。

$query = $db->prepare('SELECT name,location FROM events WHERE date >= ?'); 
$query->execute(array($startDate)); 

$insertContact = $db->prepare('INSERT INTO companies (company_name, country, ...) VALUES (?, ?, ...)'); 
$insertContact->execute(array('SMERSH', 'USSR', ...)); 

創建PDO對象(也連接到數據庫,因此是一個對口mysql_connect)很簡單:

$db = new PDO('mysql:host=localhost;dbname=db', 'user', 'passwd'); 

你不應該在每一個腳本這分散你想要一個DB連接。首先,它更具有安全風險。另一方面,你的代碼會更容易受到拼寫錯誤的影響。該解決方案解決了這兩個問題:創建一個設置數據庫連接的函數或方法。例如:

function localDBconnect($dbName='...') { 
    static $db = array(); 
    if (is_null($db[$dbName])) { 
     $db[$dbName] = new PDO("mysql:host=localhost;dbname=$dbName", 'user', 'passwd'); 
     $db[$dbName]->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } 
    return $db[$dbName]; 
} 

如果你有兩個以上或三個元素的數組工作,你應該使用循環或數組的功能,而不是類似表述的長序列,如示例代碼來完成。例如,您的大部分示例都可以替換爲:

$array = array(); 
foreach ($_POST as $key => $val) { 
    $array[$key] = "'" . mysql_real_escape_string(stripslashes($val)) . "'"; 
} 

下面是創建插入查詢的更全面的示例。這遠遠沒有準備好,但它說明了基礎知識。

$db = localDBconnect(); 

// map input fields to table fields 
$fields = array(
    'company' => 'company_name', 
    'country' => 'country', 
    'lang' => 'chat_language', 
    'fname' => 'contact_firstname', 
    'lname' => 'contact_lastname', 
    'email' => 'email', 
    'land' => 'tel_fix', 
    'mobile' => 'tel_mob', 
    'addr' => 'address', 
    'rating' => 'rating', 
); 
if ($missing = array_diff_key($fields, $_POST)) { 
    // Form is missing some fields, or request doesn't come from the form. 
    ... 
} else { 
    $registration = array_intersect_key($_POST, $fields); 

    $stmt = 'INSERT INTO `dbname`.`Companies` (`' 
     . implode('`, `', $fields) . '`) VALUES (' 
     . implode(', ', array_fill(0, count($registration), '?')) . ')'; 
    try { 
     $query = $db->prepare($stmt); 
     $query->execute(array_values($registration)); 
    } catch (PDOException $exc) { 
     // log an 
     error_log($exc); 
     echo "An error occurred. It's been logged, and we'll look into it."; 
    } 
} 

爲了使生產做好準備,代碼應該被重構到功能或隱藏代碼的其他一切相關數據庫類;這被稱爲「data access layer」。使用$fields顯示了一種編寫適用於任意表結構的代碼的方法。查找「Model-View-Controller」體系結構以獲取更多信息。此外,應該進行驗證。

+0

你如何創建你的$ db對象?我試過它給了我'致命的錯誤:調用一個非對象的成員函數prepare()in..' – serhio 2010-02-21 01:08:01

+0

你點擊了帖子中的鏈接嗎?那個說準備好的陳述的藍色文本? – Marius 2010-02-21 01:41:50

+1

@Marius:是「藍色文字」:)我是PHP的新手,不在此論壇:) – serhio 2010-02-21 10:59:39

5

以爲我會貢獻一個選項來回答「PHP中是否有將函數添加到字符串中的函數?」的問題。 - yes, you can使用str_pad(),儘管手動操作可能更容易。使用此功能做的

好處是,你也可以傳遞一個字符環繞變量本身內PHP:

function str_wrap($string = '', $char = '"') 
{ 
    return str_pad($string, strlen($string) + 2, $char, STR_PAD_BOTH); 
} 

echo str_wrap('hello world');  // "hello world" 
echo str_wrap('hello world', '@'); // @hello [email protected] 
1

這不是一個功能 - 但它的出現後的第一次在google上輸入「php wrap string in quotes」。如果有人只是想用引號括現有的字符串,而無需通過函數首先運行它,這裏是正確的語法:

echo $var // hello 

$var = '"'.$var.'"'; 

echo $var // "hello"