最近公司换了yaf框架,突然对用c实现php拓展感兴趣了,如果一个功能已经很稳定很成熟而且用的地方很多,那么我们就可以尝试用拓展实现(不一定每种情况都可以写成拓展),写成拓展后就不用每次用都包含一下,工具类直接随php启动加载进内存里。 我这次是把用
最近公司换了yaf框架,突然对用c实现php拓展感兴趣了,如果一个功能已经很稳定很成熟而且用的地方很多,那么我们就可以尝试用拓展实现(不一定每种情况都可以写成拓展),写成拓展后就不用每次用都包含一下,工具类直接随php启动加载进内存里。
我这次是把用户会话加密类写成了php的拓展,用户类是基于des加密的,主要实现了,
我给这个项目起名slime(史莱姆),勇者斗恶龙里的小怪,黏黏的。。。。。。
ok,先来看下php的实现,因为我们是php -> c,所以先看下php的实现,其实就是很普通用户类
<span> 1</span> <span>php </span><span> 2</span> <span>class</span><span> Session_DES </span><span> 3</span> <span>{ </span><span> 4</span> <span>var</span> <span>$key</span><span>; </span><span> 5</span> <span>var</span> <span>$iv</span>; <span>//</span><span>偏移量</span> <span> 6</span> <span> 7</span> <span>function</span> Session_DES( <span>$key</span>="AAAAAAAA", <span>$iv</span>="BBBBBBBB"<span>) { </span><span> 8</span> <span>//</span><span>key长度8例如:1234abcd</span> <span> 9</span> <span>$this</span>-><span>key</span> = <span>$key</span><span>; </span><span>10</span> <span>if</span>( <span>$iv</span> == ""<span> ) { </span><span>11</span> <span>$this</span>->iv = <span>$key</span>; <span>//</span><span>默认以$key 作为 iv</span> <span>12</span> } <span>else</span><span> { </span><span>13</span> <span>$this</span>->iv = <span>$iv</span>; <span>//</span><span>mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM );</span> <span>14</span> <span> } </span><span>15</span> <span> } </span><span>16</span> <span>17</span> <span>function</span> encrypt(<span>$str</span><span>) { </span><span>18</span> <span>//</span><span>加密,返回大写十六进制字符串</span> <span>19</span> <span>$size</span> = mcrypt_get_block_size ( MCRYPT_DES,<span> MCRYPT_MODE_CBC ); </span><span>20</span> <span>$str</span> = <span>$this</span>->pkcs5Pad ( <span>$str</span>, <span>$size</span><span> ); </span><span>21</span> <span>return</span> <span>strtoupper</span>( <span>bin2hex</span>( mcrypt_cbc(MCRYPT_DES, <span>$this</span>-><span>key</span>, <span>$str</span>, MCRYPT_ENCRYPT, <span>$this</span>-><span>iv ) ) ); </span><span>22</span> <span> } </span><span>23</span> <span>24</span> <span>function</span> decrypt(<span>$str</span><span>) { </span><span>25</span> <span>//</span><span>解密</span> <span>26</span> <span>$strBin</span> = <span>$this</span>->hex2bin( <span>strtolower</span>( <span>$str</span><span> ) ); </span><span>27</span> <span>$str</span> = mcrypt_cbc( MCRYPT_DES, <span>$this</span>-><span>key</span>, <span>$strBin</span>, MCRYPT_DECRYPT, <span>$this</span>-><span>iv ); </span><span>28</span> <span>$str</span> = <span>$this</span>->pkcs5Unpad( <span>$str</span><span> ); </span><span>29</span> <span>return</span> <span>$str</span><span>; </span><span>30</span> <span> } </span><span>31</span> <span>32</span> <span>function</span> hex2bin(<span>$hexData</span><span>) { </span><span>33</span> <span>$binData</span> = ""<span>; </span><span>34</span> <span>for</span>(<span>$i</span> = 0; <span>$i</span> strlen ( <span>$hexData</span> ); <span>$i</span> += 2<span>) { </span><span>35</span> <span>$binData</span> .= <span>chr</span> ( <span>hexdec</span> ( <span>substr</span> ( <span>$hexData</span>, <span>$i</span>, 2<span> ) ) ); </span><span>36</span> <span> } </span><span>37</span> <span>return</span> <span>$binData</span><span>; </span><span>38</span> <span> } </span><span>39</span> <span>40</span> <span>function</span> pkcs5Pad(<span>$text</span>, <span>$blocksize</span><span>) { </span><span>41</span> <span>$pad</span> = <span>$blocksize</span> - (<span>strlen</span> ( <span>$text</span> ) % <span>$blocksize</span><span>); </span><span>42</span> <span>return</span> <span>$text</span> . <span>str_repeat</span> ( <span>chr</span> ( <span>$pad</span> ), <span>$pad</span><span> ); </span><span>43</span> <span> } </span><span>44</span> <span>45</span> <span>function</span> pkcs5Unpad(<span>$text</span><span>) { </span><span>46</span> <span>$pad</span> = <span>ord</span> ( <span>$text</span> {<span>strlen</span> ( <span>$text</span> ) - 1<span>} ); </span><span>47</span> <span>if</span> (<span>$pad</span> > <span>strlen</span> ( <span>$text</span><span> )) </span><span>48</span> <span>return</span> <span>false</span><span>; </span><span>49</span> <span>if</span> (<span>strspn</span> ( <span>$text</span>, <span>chr</span> ( <span>$pad</span> ), <span>strlen</span> ( <span>$text</span> ) - <span>$pad</span> ) != <span>$pad</span><span>) </span><span>50</span> <span>return</span> <span>false</span><span>; </span><span>51</span> <span>return</span> <span>substr</span> ( <span>$text</span>, 0, - 1 * <span>$pad</span><span> ); </span><span>52</span> <span> } </span><span>53</span> }
再来看Session_User
<span> 1</span> <span>php </span><span> 2</span> <span>define</span> ('BACK_AUTH_NAME','xxxx'); <span>//</span><span>用到的cookie名</span> <span> 3</span> <span>class</span><span> Session_User { </span><span> 4</span> <span>static</span> <span>$obj</span><span>; </span><span> 5</span> <span>private</span> <span>$uid</span><span>; </span><span> 6</span> <span>private</span> <span>$username</span><span>; </span><span> 7</span> <span>private</span> <span>$chineseName</span><span>; </span><span> 8</span> <span>public</span> <span>$auth_name</span> =<span> BACK_AUTH_NAME; </span><span> 9</span> <span>private</span> <span>$login_url</span> = <span>null</span><span>; </span><span> 10</span> <span>public</span> <span>$domain</span> = <span>null</span><span>; </span><span> 11</span> <span> 12</span> <span>private</span> <span>function</span> __construct(<span>$login_url</span> = <span>null</span>, <span>$domain</span> = <span>null</span><span>){ </span><span> 13</span> <span>$host</span> = <span>$_SERVER</span>["HTTP_HOST"<span>]; </span><span> 14</span> <span>if</span> (!<span>$login_url</span><span>) { </span><span> 15</span> <span>$this</span>->login_url = "http://{<span>$host</span>}/login"<span>; </span><span> 16</span> <span> } </span><span> 17</span> <span>else</span><span> { </span><span> 18</span> <span>$this</span>->login_url = <span>$login_url</span><span>; </span><span> 19</span> <span> } </span><span> 20</span> <span> 21</span> <span>if</span> (!<span>$domain</span><span>) { </span><span> 22</span> <span>$domain</span> = <span>$_SERVER</span>["SERVER_NAME"<span>]; </span><span> 23</span> <span>$this</span>->domain = <span>$domain</span><span>; </span><span> 24</span> <span> } </span><span> 25</span> <span> 26</span> <span>if</span> (<span>empty</span> ( <span>$_COOKIE</span> [<span>$this</span>-><span>auth_name] )) { </span><span> 27</span> <span>return</span><span>; </span><span> 28</span> <span> } </span><span> 29</span> <span> 30</span> <span>list</span> ( <span>$uid</span>, <span>$username</span>, <span>$ua</span>, <span>$tm</span>, <span>$chineseName</span> ) = @<span>$this</span>->decodeAuth (<span>$_COOKIE</span> [<span>$this</span>-><span>auth_name]); </span><span> 31</span> <span> 32</span> <span> 33</span> <span>//</span><span>ua检验</span> <span> 34</span> <span>if</span> (<span>empty</span> ( <span>$uid</span> ) || <span>$ua</span> !== <span>md5</span>(<span>$_SERVER</span> ['HTTP_USER_AGENT'<span>])) { </span><span> 35</span> <span>return</span><span>; </span><span> 36</span> <span> } </span><span> 37</span> <span> 38</span> <span>//</span><span>TODO:过期时间检验</span> <span> 39</span> <span> 40</span> <span>$this</span>->uid = <span>$uid</span><span>; </span><span> 41</span> <span>$this</span>->username = <span>$username</span><span>; </span><span> 42</span> <span>$this</span>->chineseName = <span>$chineseName</span><span>; </span><span> 43</span> <span> } </span><span> 44</span> <span> 45</span> <span>static</span> <span>public</span> <span>function</span> instance(<span>$login_url</span> = <span>null</span>, <span>$domain</span> = <span>null</span><span>){ </span><span> 46</span> <span>if</span>(self::<span>$obj</span><span>) </span><span> 47</span> <span>return</span> self::<span>$obj</span><span>; </span><span> 48</span> <span>else</span><span>{ </span><span> 49</span> self::<span>$obj</span> = <span>new</span> Session_User(<span>$login_url</span>, <span>$domain</span><span>); </span><span> 50</span> <span> } </span><span> 51</span> <span>return</span> self::<span>$obj</span><span>; </span><span> 52</span> <span> } </span><span> 53</span> <span> 54</span> <span> 55</span> <span>/*</span><span>* </span><span> 56</span> <span> * 用户是否登陆 </span><span> 57</span> <span> * </span><span>*/</span> <span> 58</span> <span>public</span> <span>function</span><span> isLogin(){ </span><span> 59</span> <span>if</span>(! <span>empty</span>(<span>$this</span>-><span>uid)) </span><span> 60</span> <span>return</span> <span>true</span><span>; </span><span> 61</span> <span>else</span> <span> 62</span> <span>return</span> <span>false</span><span>; </span><span> 63</span> <span> } </span><span> 64</span> <span>/*</span><span>* </span><span> 65</span> <span> * </span><span> 66</span> <span> * 跳转到登录页面 </span><span> 67</span> <span> * @param unknown_type $forward </span><span> 68</span> <span> * @param unknown_type $exit </span><span> 69</span> <span>*/</span> <span> 70</span> <span>public</span> <span>function</span> requireLogin(<span>$forward</span> = '', <span>$exit</span> = <span>true</span><span>){ </span><span> 71</span> <span>if</span>(! <span>$this</span>-><span>isLogin()){ </span><span> 72</span> <span>if</span>(<span>$forward</span> === <span>null</span><span>) </span><span> 73</span> <span> { </span><span> 74</span> <span>header</span>("location: " . <span>$this</span>-><span>login_url); </span><span> 75</span> <span> 76</span> <span> } </span><span> 77</span> <span>else</span> <span> 78</span> <span> { </span><span> 79</span> <span>if</span>(<span>empty</span>(<span>$forward</span><span>)) </span><span> 80</span> <span> { </span><span> 81</span> <span>$forward</span> = 'http://'.<span>$_SERVER</span>['HTTP_HOST'].<span>$_SERVER</span>['REQUEST_URI'<span>]; </span><span> 82</span> <span> } </span><span> 83</span> <span>$forward</span> = <span>urlencode</span>(<span>$forward</span><span>); </span><span> 84</span> <span>header</span>("location: ". <span>$this</span>->login_url . "?forward=<span>$forward</span>"<span>); </span><span> 85</span> <span> } </span><span> 86</span> <span>if</span>(<span>$exit</span><span>) </span><span> 87</span> <span>exit</span><span>; </span><span> 88</span> <span> } </span><span> 89</span> <span> } </span><span> 90</span> <span>/*</span><span>* </span><span> 91</span> <span> * </span><span> 92</span> <span> *设置登录状态 </span><span> 93</span> <span> * @param unknown_type $uid </span><span> 94</span> <span> * @param unknown_type $username </span><span> 95</span> <span> * @param unknown_type $ua </span><span> 96</span> <span> * @param unknown_type $outtime </span><span> 97</span> <span>*/</span> <span> 98</span> <span> 99</span> <span>public</span> <span>function</span> setLogin(<span>$uid</span>, <span>$username</span>, <span>$ua</span> = <span>null</span>,<span>$outtime</span> = <span>null</span>, <span>$chineseName</span> = <span>null</span><span>){ </span><span>100</span> <span>if</span>(<span>empty</span>(<span>$ua</span><span>)){ </span><span>101</span> <span>$ua</span> = <span>$_SERVER</span>['HTTP_USER_AGENT'<span>]; </span><span>102</span> <span> } </span><span>103</span> <span>104</span> <span>$str</span> = <span>$this</span>->encodeAuth(<span>$uid</span>, <span>$username</span>, <span>$ua</span>, <span>$chineseName</span><span>); </span><span>105</span> <span>setcookie</span>(<span>$this</span>->auth_name,<span>urlencode</span>(<span>$str</span>),<span>$outtime</span>,'/',<span>$this</span>-><span>domain); </span><span>106</span> <span> } </span><span>107</span> <span>/*</span><span>* </span><span>108</span> <span> * 用户退出 </span><span>109</span> <span>*/</span> <span>110</span> <span>public</span> <span>function</span><span> setLogout(){ </span><span>111</span> <span>setcookie</span>(<span>$this</span>->auth_name,'',-1,'/',<span>$this</span>-><span>domain); </span><span>112</span> <span> } </span><span>113</span> <span>114</span> <span>public</span> <span>function</span> __get(<span>$key</span><span>){ </span><span>115</span> <span>if</span>('uid' == <span>$key</span><span>){ </span><span>116</span> <span>return</span> <span>$this</span>-><span>uid; </span><span>117</span> }<span>elseif</span> ('username' == <span>$key</span><span>) { </span><span>118</span> <span>return</span> <span>$this</span>-><span>username; </span><span>119</span> }<span>elseif</span> ('chineseName' == <span>$key</span><span>) { </span><span>120</span> <span>return</span> <span>$this</span>-><span>chineseName; </span><span>121</span> <span> } </span><span>122</span> <span>return</span><span> ; </span><span>123</span> <span> } </span><span>124</span> <span>125</span> <span>public</span> <span>function</span><span> getUid(){ </span><span>126</span> <span>return</span> <span>$this</span>-><span>uid; </span><span>127</span> <span> } </span><span>128</span> <span>129</span> <span>public</span> <span>function</span><span> getUserName(){ </span><span>130</span> <span>return</span> <span>$this</span>-><span>username; </span><span>131</span> <span> } </span><span>132</span> <span>133</span> <span>public</span> <span>function</span><span> getChineseName(){ </span><span>134</span> <span>return</span> <span>$this</span>-><span>chineseName; </span><span>135</span> <span> } </span><span>136</span> <span>137</span> <span>/*</span><span>* </span><span>138</span> <span> * 生成加密的登陆cookie </span><span>139</span> <span>*/</span> <span>140</span> <span>private</span> <span>function</span> encodeAuth(<span>$uid</span>,<span>$username</span>,<span>$ua</span>,<span>$chineseName</span>=<span>null</span><span>){ </span><span>141</span> <span>$tm</span> = <span>time</span><span>(); </span><span>142</span> <span>$ua</span> = <span>md5</span>(<span>$ua</span><span>); </span><span>143</span> <span>$info</span> = "<span>$uid</span>\t<span>$username</span>\t<span>$ua</span>\t<span>$tm</span>\t<span>$chineseName</span>"<span>; </span><span>144</span> <span>$des</span> = <span>new</span><span> Session_DES(); </span><span>145</span> <span>$str</span> = <span>$des</span>->encrypt(<span>$info</span><span>); </span><span>146</span> <span>return</span> <span>$str</span><span>; </span><span>147</span> <span> } </span><span>148</span> <span>149</span> <span>/*</span><span>* </span><span>150</span> <span> * 解析加密cookie </span><span>151</span> <span>*/</span> <span>152</span> <span>private</span> <span>function</span> decodeAuth(<span>$str</span><span>){ </span><span>153</span> <span>$des</span> = <span>new</span><span> Session_DES(); </span><span>154</span> <span>$info</span> = <span>explode</span>("\t",@<span>$des</span>->decrypt(<span>$str</span><span>)); </span><span>155</span> <span>if</span>(<span>is_array</span>(<span>$info</span><span>)){ </span><span>156</span> <span>return</span> <span>$info</span><span>; </span><span>157</span> }<span>else</span><span>{ </span><span>158</span> <span>return</span> <span>array</span><span>(); </span><span>159</span> <span> } </span><span>160</span> <span> } </span><span>161</span> <span>162</span> <span>public</span> <span>function</span> auth(<span>$controller</span>,<span>$action</span><span>) </span><span>163</span> <span> { </span><span>164</span> <span>if</span>(!<span>in_array</span>(<span>$controller</span>,<span>$conArr</span><span>)){ </span><span>165</span> <span>return</span> <span>false</span><span>; </span><span>166</span> <span> } </span><span>167</span> <span>if</span>(!<span>in_array</span>(<span>$action</span>,<span>$actArr</span><span>)){ </span><span>168</span> <span>return</span> <span>false</span><span>; </span><span>169</span> <span> } </span><span>170</span> <span>return</span> <span>true</span><span>; </span><span>171</span> <span> } </span><span>172</span> }
结合上面两段代码,分离出来其实得到的会话类(常常做的就是把一样的的跟不一样的分离出来),只需要3个变量两个是des用到的iv偏移量,key加密秘钥,跟cookie名,然后我们就可以写我们的拓展了,其中踩到了很多坑,一些makefile,config.w4等小语法,lib依赖,总之还是学到了很多
代码地址:https://github.com/lietdai/ldclass