我已經在SO上讀過幾個線程,但沒有一個似乎解決了我的問題。我甚至嘗試了一些代碼示例,但它們不適用於我。在foreach循環中雙引號字符串中的變量值不被替換
我已經花了好幾天的時間來解決這個問題,但到目前爲止我失敗了。我不認爲這是一個可變範圍問題,但我可能是錯的。由於實際的腳本太長,我只會顯示我的邏輯,我希望這已經足夠了。
主要腳本邏輯:
<?php
require_once General functions
require_once Validator class
require_once DB table setup
function ForValidationRule()
{
}
if($_POST)
{
validation rules
if(validations pass)
{
variables set
foreach(loop thru selected tables to create)
{
foreach(loop thru table array to build query)
{
$sql .= $data . PHP_EOL;
}
}
}
}
?>
這是在我的測試中使用的表數組:
$tbl_names = array
(
"`id_no` INT NOT NULL AUTO_INCREMENT,",
"`type_id` CHAR(1) NOT NULL,",
"`abbrev` VARCHAR(30) NOT NULL,",
"`description` VARCHAR(75) NULL DEFAULT NULL,",
"PRIMARY KEY (`id_no` ASC),",
"UNIQUE INDEX `type_id-abbrev` (`type_id` ASC, `abbrev` ASC))",
"ENGINE = {$engine}",
"CHARACTER SET {$charset} COLLATE {$dbcoll}",
"AUTO_INCREMENT = 2",
"COMMENT = '{$company} {$tbl_name['names']['full']}';"
);
我遇到問題的3個變量是:$發動機,$ dbcoll和$字符集。當我在構建查詢之前回顯變量時,它們是正確的。當我在構建查詢後回顯變量時,他們是正確的。但這是構建查詢的結果:
CREATE TABLE `tester`.`name_pre-suf`(
`id_no` INT NOT NULL AUTO_INCREMENT,
`type_id` CHAR(1) NOT NULL,
`abbrev` VARCHAR(30) NOT NULL,
`description` VARCHAR(75) NULL DEFAULT NULL,
PRIMARY KEY (`id_no` ASC),
UNIQUE INDEX `type_id-abbrev` (`type_id` ASC, `abbrev` ASC))
ENGINE =
CHARACTER SET COLLATE
AUTO_INCREMENT = 2
COMMENT = 'CEF, Inc. Name Prefixes/Suffixes File';
可以看出,所有3個變量在查詢中都是空白的。使用1個變量,$引擎,我嘗試了幾種方法,但都沒有工作。
"ENGINE = {${$engine}}"
"ENGINE = " . $engine
'ENGINE = ' . $engine
任何人都可以看到我做錯了什麼嗎?如果我硬編碼值而不是使用變量代碼確實工作正常。
編輯1: 我在我的原始邏輯示例中犯了一個錯誤。變量在進入任何foreach循環之前設置。我糾正了邏輯示例。這是我如何設置這些變量:
$dbhost = $_POST['dbhost'];
$dbuser = $_POST['dbuser'];
$dbpass = $_POST['dbpass'];
$dbname = $_POST['dbname'];
$dbcoll = str_ToLower($_POST['dbcoll']);
$dbcoll_ary = explode("_", $dbcoll);
$charset = trim($dbcoll_ary['0']);
$engine = 'innodb';
if($charset == 'utf8mb4')
{
$engine = 'innodb ROW_FORMAT=DYNAMIC';
}
這就是我在構建查詢和之後回聲的地方。
echo($engine . PHP_EOL);
echo($dbcoll . PHP_EOL);
echo($charset . PHP_EOL);
$sql = "CREATE TABLE `$dbname`.`{$tbl_name[$key]['db']}`(" . PHP_EOL;
foreach(${'tbl_' . $key} as $data)
{
$sql .= $data . PHP_EOL;
} // Closing brace for foreach(${'tbl_' . $key} as $data)
echo($engine . PHP_EOL);
echo($dbcoll . PHP_EOL);
echo($charset . PHP_EOL);
echo($sql . PHP_EOL);
exit();
回顯值是正確的,它們是用戶選擇的值。
編輯2: 表名和表設置在該被使用放在require_once命令包括在表文件中定義。這裏是我用於測試的表名數組和第一個表數組。
$company = defined('COMPANY_NAME_SHORT') ? COMPANY_NAME_SHORT : '';
$tbl_name = array
(
'names' => array('db' => 'name_pre-suf', 'full' => 'Name Prefixes/Suffixes File'),
'tmzn' => array('db' => 'timezones', 'full' => 'Timezones File'),
'curr' => array('db' => 'currency', 'full' => 'Currency File'),
'langtyp' => array('db' => 'language_types', 'full' => 'Language Types File'),
'lang' => array('db' => 'language', 'full' => 'Language File'),
'cntyp' => array('db' => 'country_types', 'full' => 'Country Types/Sub-Types File'),
'cntry' => array('db' => 'countries', 'full' => 'Countries'),
'terri' => array('db' => 'territories', 'full' => 'Territories'),
'trans' => array('db' => 'translations', 'full' => 'Translations'),
'langu' => array('db' => 'languages', 'full' => 'Languages'),
'curry' => array('db' => 'currencies', 'full' => 'Currencies'),
'dialc' => array('db' => 'dial_codes', 'full' => 'Dialing Codes'),
'topld' => array('db' => 'tl_domains', 'full' => 'Top Level Domains'),
'users' => array('db' => 'users', 'full' => 'Users'),
'usact' => array('db' => 'users_activity', 'full' => 'Users Activity'),
);
$tbl_names = array
(
"`id_no` INT NOT NULL AUTO_INCREMENT,",
"`type_id` CHAR(1) NOT NULL,",
"`abbrev` VARCHAR(30) NOT NULL,",
"`description` VARCHAR(75) NULL DEFAULT NULL,",
"PRIMARY KEY (`id_no` ASC),",
"UNIQUE INDEX `type_id-abbrev` (`type_id` ASC, `abbrev` ASC))",
"ENGINE = {$engine}",
"CHARACTER SET {$charset} COLLATE {$dbcoll}",
"AUTO_INCREMENT = 2",
"COMMENT = '{$company} {$tbl_name['names']['full']}';"
);
主要腳本幾乎是600線(包括所有的PHP,HTML和JavaScript),而表設置(1和表名陣列和所有單獨的表陣列)文件是大約300行。我可以在SO中附加文件嗎?
是的,你是正確的。如果我聲明並設置表格數組文件中的變量,那麼使用這些值。但是,它們不會被查詢循環中的用戶選擇所改變。用戶在腳本運行之前選擇要使用的COLLATE值。 3個變量被設置,因爲我在查詢循環之前和之後回顯它們。他們被設置。 – CharlesEF
@CharlesEF檢查我編輯的答案。 –
我已經聲明並在任何require_once之前的主腳本的最頂部設置了變量。我還聲明並設置了表格數組文件最頂部的變量。這兩種情況都會導致循環中使用的變量值是聲明的值,而不是實際的用戶選擇的值。換句話說,如果用戶選擇「utf8mb4_unicode_ci」,則仍然使用「utf8_general_ci」。 – CharlesEF