月度归档:2013年04月

深圳港澳通行证和护照办理攻略

深圳港澳通行证和护照办理攻略

来深圳有些年了,一直没有办港澳通行证,一是没有如此强烈的需求,有些东西直接网上买了,二是懒了,不想跑。但是,现在到时间点了,得隔几周去一次香港搬点东西回来,毕竟那边有些东西还是靠谱一些。于是打算去办个通行证,和强哥聊的时候,强哥说既然都去了,干脆连接护照也一起办了吧,所需要的东西反正是一样的,准备两份就好了。在一通折腾后总算是把证办完了,趁着回执还热乎,写下这篇短文,希望能给后续有同样需求的朋友一些帮助。

与其说这是一个攻略,不如说是如何更快的在办证现场搞定这个事。这里没有各种细节说明,也没有各种文件下载,说的只是一个减少你在办证大厅的时间的过程。

以下流程仅适用于深圳地区。

这事主要是两点,一是提前预约,二是提前准备。

提前预约

提前预约是指提前在 【深圳市公安局出入境便民网】 上预约办证。预约地址:http://www.sz3e.com:8000/。输入身份证、选择受理单位,选择预约的日期和时间段,提交。然后在你预约的时间去办大厅咨询处取预约号,坐下等会儿应该就轮到你办了。可能在你前面还有若干个人,嘿嘿。很爽的感觉。这里建议提前30分钟到,不到你预约的点,工作人员是不会给你预约号的。

提前准备

提前准备是指提前将所需要的材料准备好,如果你是深户,那么准备好身份证及其复印件、户口本及其复印件。资料OK后就是准备填写表格,表格可以到办证大厅去拿,也可以自已拿,为了减少时间,我们还是自己去下载打印,填好后直接过去办就可以了。在这里可以下载到护照和通行证的表格。这些都准备好了,就剩下照片了,如果你没有照片回执,那么找个照相馆拍一张吧,实惠。如果你想偷懒,去大厅那边拍吧,就是有点贵。另外,由于我们要办两个证,所以回执需要复印一张,如果有其它需求,多复印几张也是可以的。嗯,办证大厅的复印也挺贵的。

其它信息

如果有些事情无法确定,提前打电话确认下吧。

另外说一句,这个网站的类别id有些奇怪,用的.net、tomcat。

foreach的指针问题

在PHP中,foreach 语法结构提供了遍历数组的简单方式。 foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量,将导致错误。 foreach每次循环时,当前单元的值被赋给 $value 并且数组内部的指针向前移一步(因此下一次循环中将会得到下一个单元)。

但是手册中提醒我们:

Note:
当 foreach 开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在 foreach 循环之前调用 reset()。
在循环中修改 foreach 依赖其内部数组指针将可能导致意外的行为。

这里我们所要说的是foreach可能导致的意外情况。如代码1示例:

<?php
$arr = array(1,2,3,4,5);
 
foreach($arr as $key => &$row) {
echo key($arr), '=>', current($arr), "\r\n";
}

会输出什么?

如代码2示例呢?

<?php
$arr = array(1,2,3,4,5);
 
foreach($arr as $key => $row) {
echo key($arr), '=>', current($arr), "\r\n";
}

会输出什么?

代码1会依次输出变量,但是第一个元素并没有在输出结果中出现。

代码2只会输出数组的第二个元素。

为什么呢?

将代码2在VLD扩展中查看,

number of ops:  22
compiled vars:  !0 = $arr, !1 = $key, !2 = $row
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   INIT_ARRAY                                       ~0      1
         1      ADD_ARRAY_ELEMENT                                ~0      2
         2      ADD_ARRAY_ELEMENT                                ~0      3
         3      ADD_ARRAY_ELEMENT                                ~0      4
         4      ADD_ARRAY_ELEMENT                                ~0      5
         5      ASSIGN                                                   !0, ~0
   4     6    > FE_RESET                                         $2      !0, ->20
         7  > > FE_FETCH                                         $3      $2, ->20
         8  >   ZEND_OP_DATA                                     ~5      
         9      ASSIGN                                                   !2, $3
        10      ASSIGN                                                   !1, ~5
   5    11      SEND_REF                                                 !0
        12      DO_FCALL                                      1  $7      'key'
        13      ECHO                                                     $7
        14      ECHO                                                     '%3D%3E'
        15      SEND_REF                                                 !0
        16      DO_FCALL                                      1  $8      'current'
        17      ECHO                                                     $8
        18      ECHO                                                     '%0D%0A'
   6    19    > JMP                                                      ->7
        20  >   SWITCH_FREE                                              $2
   8    21    > RETURN                                                   1

从上面VLD扩展输出结果结合PHP的源代码可以知道,在foreach遍历之前, PHP内核首先会有个FE_RESET操作来重置数组的内部指针,也就是pInternalPointer, 然后通过每次FE_FETCH将pInternalPointer指向数组的下一个元素,从而实现顺序遍历。
并且每次FE_FETCH的结果都会被一个全局的中间变量存储,以给下一次的获取元素使用。

从这两个例子可以引申出三个问题:

1、为什么foreach循环体中执行key或current会显示第二个元素(非引用情况)?
以key函数为例,我们执行函数调用时,会执行中间代码SEND_REF,此中间代码会将没有设置引用的变量复制一份并设置为引用。当进入循环体时,PHP内核已经经过了一次fetch操作,相当于执行了一次next操作,当前元素指向第二个元素。因此我们在foreach的循环体中执行key函数时,key中调用的数组变量为PHP执行了一次fetch操作的数组拷贝,此时foreach的内部指针指向第二个元素。

2、为什么在foreach中执行end等操作,其循环过程不变?
在遍历的代码中通过end,next等操作数组的指针,数组的指针不会变化,这是因为在PHP内核进行FETCH操作时,会通过中间变量存储当前操作数组的内部指针,每遍历一个元素,会先获取之前存储的指针位置,获取下一个元素后,再恢复指针位置。

3、为什么$row的引用和非引用情况下输出结果不同?
如果是引用,PHP内核在reset数组时,会直接分裂数组,生成一个数组的拷贝,并将其设置为引用。
如果是非引用,PHP内核在reset数组时,当数组的引用计数大于1,并且不存在引用时,会拷贝数组供foreach使用,其它情况使用原数组,将其引用计数加1。

因为引用的不同,在循环体中给函数传递参数时其结果不同,导致看到的foreach数组内部指针变化的不同。对于非引用且引用计数大于1的情况,其本身就是两个不同的数组,在RESET时就不同了。