这有点难以解释,但我会尽力解释它尽可能好。
我将数据从一页input textfield
上的(page1.php)
传递到另一页Select form
上的(page2.php)
。
这应该是有效的。
Select Form
包含一些PHP timezones
,当选择时区时,页面将回显该时区的当前时间。
这也可行。
问题是当我在(page1.php)
的输入文本字段中输入时区名称时,它会在(page2.php)
的选择表单中显示名称,但它不会回显当前时间,它会抛出出了这个错误:
Fatal error: Uncaught exception 'Exception' with message 'DateTimeZone::__construct(): Unknown or bad timezone (London)' in page2.php:16 Stack trace: #0 on line 16.
当事实时区伦敦存在于Select Form Options
时,如果我直接在选择表格中输入/搜索伦敦,它将回显该时区的当前时间,但如果输入时区名称则不会page1.php上的输入文本字段,它被传递给page2.php!
这是我在page2.php上的内容:
<?php
if( isset($_POST['submit']))
{
//be sure to validate and clean your variables
$timezone2 = htmlentities($_POST['timezone2']);
//then you can use them in a PHP function.
function get_timezone_offset( $remote_tz ) {
$timezone2 = new DateTimeZone ( $remote_tz ); ----->>> Line 16 is here.
$datetime2 = new DateTime ("now", $timezone2);
$offset = $timezone2->getOffset($datetime2);
return $offset;
}
$offset = get_timezone_offset($timezone2);
}
?>
<?php
$options = array();
$options[$_POST["location"]] = $_POST["location"]; <<<<<<----- Data from input textfield on page1.php
$options["Africa/Addis_Ababa"] = "Addis Ababa"; <<<<<<----- Select Form Options
$options["Europe/London"] = "London"; <<<<<<----- Select Form Options
?>
以下是page2.php上的选择表单
<form id="myForm" name="myForm" class="myForm" method="post" action="page2.php">
<select style="font-size:9px;" name="timezone2" id="timezone2" class="timezone2">
<?php
foreach($options as $key => $value)
{
echo '<option value="'. $key .'" label="'. $value .'">'.$value.'</option>';
}
?>
<option value="<?php echo $_POST["location"]; ?>"><?php echo $_POST["location"]; ?></option>
</select>
</div>
<div id="myBtn" style="position:relative; float:left; width: 228px; margin-top:50px; margin-left:350px;"><input type="submit" name="submit" id="submit" class="submit" value="Search"/></div>
</form>
,这是page1.php
上的输入文本字段<form method="post" action="../page2.php">
<input name="location" type="text" value="Search"/>
<button type="submit">Search</button>
</form>
有人可以指出我正确的方向吗?
答案 0 :(得分:2)
出于某些原因,你会出现这种错误。首先,可能的时区列表是有限的,所以摆脱文本字段,只需使用下拉列表。
其次,您可以删除\重命名下拉列表中的所有项目,但只记得因为您要保存偏移量而不是tz名称,所以您永远无法返回(我的示例将向您显示为什么如果您玩它)。通常,最好存储名称而不是偏移量,以便您可以正确管理夏令时。你会注意到为了让这个系统工作,我需要调用date('I')来查看它是否真的很糟糕的夏令时(因为它在我的服务器TZ中的夏令时并不意味着它在用户TZ)。如果您保存了TZ名称,则可以将该逻辑推迟到PHP并使用当前的任何偏移量。在这个简单的例子中,这似乎并不重要,但如果您曾尝试存储该偏移量或使用它来计算未来\过去时间,那么您肯定会遇到麻烦。
另一个小问题是将函数定义放在'if'语句中是很奇怪的。在PHP中,所有函数定义都是全局的,因此无论'if'条件是否为真,它都可用。这样做的问题是你现在已经模糊了你的逻辑而没有任何收获。将其放在别处更容易也更清楚。
我已经重新编写了你的代码,以便在使用它时实际工作但是我遗漏了一些细节(比如别名TZ名称[你似乎已经掌握了如何做并切换到使用TZ名称而不是偏移[因为这可能会破坏你的其他代码])但我鼓励你也修复它们。
<?php
$tz_offset=0;
function get_offset_time($offset=0) {
$original=new DateTime("now");
$timezoneName=timezone_name_from_abbr("", $offset, date('I'));
if(!$timezoneName) die('ERROR: Unknown timezone \''.($offset/3600).'\'');
$oTZ=new DateTimezone($timezoneName);
$modified = $original->setTimezone($oTZ);
return $modified->format('Y-m-d H:i:s');
}
function get_timezone_offset($tz_name=null) {
if(!$tz_name) return 0; // If we have invalid data then return before we error
$tz=new DateTimeZone($tz_name);
$dt=new DateTime("now", $tz);
return $tz->getOffset($dt);
}
function enumerate_tz($tz_select=null) {
global $tz_offset;
$tz_ident=DateTimeZone::listIdentifiers();
foreach($tz_ident as $val) {
$tmp_offset=get_timezone_offset($val);
if($val=='UTC'||$tmp_offset)
echo '<option value="'.$val.'" '. ($tmp_offset==$tz_offset?' selected':''). '>'.
$val. ' [ '.($tmp_offset/3600).' ]'. // If you'd like to customize the viewable names for each TZ you may do so here
'</option>';
}
}
if(isset($_POST['tz_input']) && $_POST['tz_input']) {
$tz_input=htmlentities($_POST['tz_input']);
$tz_offset=get_timezone_offset($tz_input);
}
echo '<html><title>Timezone Select</title><body>'.
'<p>The current timezone offset is: '. ($tz_offset? ($tz_offset/3600): '0'). '</p>';
echo '<p>The current time is: '. get_offset_time($tz_offset). '</p>';
echo '<form method=post><select name=tz_input>';
enumerate_tz($tz_offset); // You'll notice that this list duplicates many of the timezones so that after selecting one the next
// time through it'll often select a different one. If you want to fix that you'll need to save the actually offset name instead of an offset.
echo '</select><input type=submit value=Search />'.
'</form></body>';
?>
编辑:另外需要注意的是PHP的timezone_name_from_abbr()函数不完整。某些时区偏移量不会返回TimeZone名称。你也必须考虑到这一点。例如,即使PHP理解“太平洋/中途”时区,在进行反向查找时也无法找到它。我已经更新了代码,因此不会再导致硬错误。
EDIT2:我可以看到,除非有人告诉你如何照亮粪便,否则你不会高兴。你走了:
function getOptionDX($val, $option_array) {
if(!isset($option_array)||!is_array($option_array)||!count($option_array)>0||!$val) return null;
$val=htmlentities($val);
if(isset($option_array[$val])) return $val;
$new_val=array_search($val, $option_array);
return $new_val!==FALSE?$new_val: null;
}
将此添加到您的代码中,并通过调用此代码来替换对htmlentities的调用:
$timezone2 = getOptionDX($_POST['timezone2'], $options);
最后,更改此行:
if($timezone2) $offset = get_timezone_offset($timezone2);
如果用户手动输入TZ并且正确,则跳过page2.php。如果您不想更改任何内容,这可以给出答案。事实上,你的逻辑首先是有缺陷的(这并不意味着刺戳,但确实如此)。
EDIT3:IDK出了什么问题,但这是我的完整代码清单,其中包含您要求的修补程序:
<?php
$offset=0; $timezone2='';
$options = array();
$options["Africa/Addis_Ababa"] = "Addis Ababa";
$options["Europe/London"] = "London";
$options["America/Chicago"] = "The Windy City";
function getOptionDX($val, $option_array) {
if(!isset($option_array)||!is_array($option_array)||!count($option_array)>0||!$val) return null;
$val=htmlentities(ucwords(strtolower($val)));
if(isset($option_array[$val])) return $val;
$new_val=array_search($val, $option_array);
return $new_val!==FALSE?$new_val: null;
}
function get_timezone_offset( $remote_tz ) {
$timezone2=new DateTimeZone($remote_tz);
$datetime2=new DateTime("now", $timezone2);
$offset=$timezone2->getOffset($datetime2);
return $offset;
}
if(isset($_POST['location'])) {
$addLoc=getOptionDX($_POST['location'], $options);
if(isset($addLoc)) $options[$addLoc]=$_POST['location'];
else header('Location: '. $_SERVER['SCRIPT_NAME']);
}
if(isset($_POST['timezone2'])) {
$timezone2=htmlentities($_POST['timezone2']);
$offset=get_timezone_offset($timezone2);
}
if(isset($_GET['page2'])) {
?>
<form method=post action=?page2>
<select name=timezone2>
<?php foreach($options as $key=>$value) echo "\t".'<option value="'. $key .'"'.(get_timezone_offset($key)==$offset?' selected':'').'>'.$value.'</option>'."\n"; ?>
</select>
<input type=hidden name=location type="text" value="<?php echo $_POST['location']; ?>"/>
</div>
<input type=submit value=Search>
</form>
<p>Current Offset: <?php echo $offset/3600; ?></p>
<p>Current Time: <?php echo gmdate('Y-m-d H:i:s'); ?> UTC</p>
<p>Current Time: <?php echo gmdate('Y-m-d H:i:s', time()+$offset).' '. $timezone2; ?> </p>
<?php
} else {
?>
<form method=post action=?page2>
<input name=location type=text value=""/>
<button type=submit>Search</button>
</form>
<?php
}
?>
我已经对此进行了测试并知道它有效,如果这还不足以回答你的问题,那么我就放弃了。我开始认为你真的想要一种方法来发明不存在的新时区。那是不可能的。你可以将已存在的那些已经存在,就像我在这里所做的那样,它就像你将要获得的那样接近。从逻辑上讲,时区的范围只能在-12:00到+12:00之间,几乎每个已知的时区都已经计算好了,所以如果这还不够,你别无选择,只能重新考虑你的设计。