整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          一個wordpress下轉(zhuǎn)義符的怪事及解決方法

          天,有漁老師去現(xiàn)場為一位朋友解決一個網(wǎng)站注冊驗證的問題。問題是這樣的:在朋友的網(wǎng)站用郵箱注冊后,系統(tǒng)會發(fā)一封郵件到郵箱,然后點擊鏈接設(shè)置賬號的初始化密碼。如下圖所示:

          但我點擊這個鏈接后,wordpress一直提示invalid key,也就是說key錯誤。因為是wordpress框架,從url的路由看,我就打開wp-login.php,然后查看其中的action rp。我直觀感覺,應(yīng)該是get url中的key跟數(shù)據(jù)庫中的key值不相等導致的。所以,想進入系統(tǒng)的mysql一查究竟,但遺憾的是竟然沒有mysql權(quán)限,我也不知道他的網(wǎng)站是讓誰做的,估計是個外包吧。因為朋友是不懂技術(shù)的,很多事情問他也是一問三不知。沒辦法,哪就自己悶頭搞吧。

          外事不決問google,內(nèi)事不決問baidu。我習慣性地打開baidu,輸入:wordpress新用戶注冊 key無效。發(fā)現(xiàn)碰到類似問題的同行也不少,且看他們是如何解決的?他們的建議是:

          編輯wp-includes文件夾中的pluggable.php文件,把變量$message里的>符合去掉。我照做了,發(fā)現(xiàn)還是不行的哦。所以,網(wǎng)上的東西,很多都得自己再實踐下,否則是要被坑的。但到這一步,我更加確信是key的值出問題了。然后我又仔細看了下郵件發(fā)送過來的鏈接,發(fā)現(xiàn)這個鏈接有個問題。

          這個鏈接里的&是&被轉(zhuǎn)義后的值。那么,我在瀏覽器里輸入時把&替換成&會怎樣呢?發(fā)現(xiàn)竟然OK了,這時密碼重置成功了。這樣,問題就好辦了,理論上,我只要修改pluggable.php,把&替換成&就可以了。$message的變量賦值如下:

          $message .= ‘<‘ . network_site_url(“wp-login.php?action=rp&key=$key&login=” . rawurlencode($user->user_login), ‘login’) . “>\r\n\r\n”;

          但問題是,我用htmlspecialchars_decode($message)處理也不行,用str_replace("&amp;","&",$message)處理也不行。也就是說,這個&amp;替換不成&。

          我再看這$message變量,rp后面的&怎么沒被轉(zhuǎn)義,而$key后面的&卻被轉(zhuǎn)義了。所以,到這一步,我就懷疑是不是語句的順序有問題?然后,我就把&key=$key放到($user->user_login)后面。然后,根據(jù)前面baidu的一些意見,順便把<和>符合也去掉。這樣,修改后的message如下:

          $message .= network_site_url(“wp-login.php?action=rp&login=” . rawurlencode($user->user_login)."&key=$key", ‘login’) . “\r\n\r\n”;

          問題就這樣解決了。

          總結(jié):1,出現(xiàn)問題,問baidu一般都能找到一些建議。但這些建議不一定完全正確,自己還得根據(jù)實際情況修改。2,html的一些特殊符號,在存數(shù)據(jù)庫之前需要被轉(zhuǎn)義,在取出數(shù)據(jù)庫后,需要被轉(zhuǎn)換回來,這也是一個很重要的知識點。

          mybatis 的 xml 文件里寫的 sql 語句實際用的是一門叫做 OGNL 的表達式語言,OGNL 全稱 Object Graph Navigation Language 對象圖導航語言,是常應(yīng)用于 Java 中的一個開源的表達式語言(Expression Language),它被集成在 Spring、Mybatis、Struts2 等 Java 框架中,通過簡單一致的表達式語法,可以存取對象的任意屬性,調(diào)用對象的方法,遍歷整個對象的結(jié)構(gòu)圖,實現(xiàn)類型轉(zhuǎn)化等功能。

          在書寫動態(tài) SQL 時經(jīng)常需要借助各種標簽,下面是一些在 mybatis 中常用的標簽:

          if 標簽

          • 沒有 else、else if 標簽
          • if 標簽可以嵌套
          • if 標簽判斷條件 test 中可以用 or 的,我們經(jīng)常看到用 and
          • 對于 number 類型,0 或者浮點型 0.00 會被當成 false(和 js 類似)
          • 對于字符串類型才需要判斷 != '',其他類型直接判斷 != null 就行了
          • 對于空字符串 "" 會被當成 false
          • 單引號內(nèi)只有一個字符時,OGNL 會識別成 java 中的 char 類型,然后數(shù)據(jù)如果是 String 類型時會導致判斷失效,可以直接將 test 的引號改成單引號,然后里面的字符串用雙引號

          if 標簽的 test 中常用判斷:

          * 相等:==
          * 不等:!=
          * 條件或:or
          * 條件與:and
          * 條件非:!,也可以用 not
          * 包含:in
          * 不包含:not in
          * 小于:<
          * 小于等于:<=
          * 大于:>
          * 大于等于:>=

          choose、when、otherwise 標簽

          相當于 if、else if、else,間接實現(xiàn)了上面 if 標簽不支持的 else 效果

          where 標簽

          用于拼接 SQL 語句中的 where 子句,條件成立時才會加上 where 關(guān)鍵字,可以避免拼接出多余的and、or

          set 標簽

          • 用于拼接SQL語句中的set子句,與 update 語句配合使用,條件成立時才會加上 set 關(guān)鍵字,可以避免拼接出多余的逗號,如果有多余的標簽 set 標簽會自動去掉
          • 一定會加上 set 關(guān)鍵字,所以要保證至少有一個條件成立,否則會報 SQL 語法錯誤
          <update id="updateUserInfo" parameterType="UserInfo">
              update t_user_info
              <set>
                  <if test="userName != null and userName != ''">
                      user_name = #{userName},
                  </if>
                  <if test="age != null">
                      age = #{age},
                  </if>
              </set>
              where user_id = #{userId}
          </update>

          trim 標簽

          可以間接實現(xiàn) where 和 set 標簽一樣的功能

          foreach 標簽

          遍歷集合類數(shù)據(jù),標簽屬性:

          • collection:要被遍歷解析的對象,集合名或者數(shù)組名
          • item:集合或數(shù)組中每一個迭代元素的別名
          • index:在 list 和數(shù)組中為元素序號,在 map 中為元素的 key
          • open:開始符號
          • close:結(jié)束符號
          • separator:連接每一項的分割符號

          collection 接收的參數(shù):

          • 匿名參數(shù):當在 java 方法中沒有通過 @Param 注解指定參數(shù)名時,列表類型默認參數(shù)名為 list,數(shù)組為 array,注意 Map 無默認值需要自己指定具名參數(shù)
          • 具名參數(shù):java 方法中使用了 @Param 注解指定了參數(shù)名稱,則 foreach 中的 collection 屬性必須為指定的參數(shù)名

          示例1:匿名參數(shù)

          <!-- mapper -->
          int insertUsers(List<User> users);
          int updateUsers(List<User> users);
          
          <!-- xml -->
          <insert id="insertUsers">
              insert into t_user (id, user_name, age) values
              <foreach collection="list" separator="," item="user">
                  (#{user.user_id}, #{user.user_name}, #{user.age})
              </foreach>
          </insert>
          
          <update id="updateUsers">
              <foreach collection="list" separator=";" item="user">
                  update t_user
                  <set>
                      <if test="user.userName != null and user.userName != ''">
                          user_name= #{user.userName},
                      </if>
                      <if test="user.age != null">
                          age= #{user.age},
                      </if>
                  </set>
                  where user_id = #{user.userId}
              </foreach>
          </update>

          示例2:具名參數(shù)

          <!-- mapper -->
          List<User> selectUsers(@Param("userIds") String[] userIds);
          
          <!-- xml -->
          <select id="selectUsers" resultType="User">
               select * from t_user where user_id in
               <foreach collection="userIds" item="item" open="(" close=")" separator=",">
                  #{item}
               </foreach>
          </select>

          更多參數(shù)傳遞可以參考后面的 mybatis 參數(shù)章節(jié)。

          sql、include 標簽

          可以在 sql 標簽里定義語句,然后在需要的地方用 include 標簽引入進去,可以實現(xiàn)代碼片段復用。

          selectKey 標簽

          用于配合插入數(shù)據(jù)成功后返回的數(shù)據(jù),一般用來返回 id 之類的。

          mybatis 中參數(shù)傳遞

          主要有以下 5 種傳參方式:

          • 匿名參數(shù)
          • 具名參數(shù),需用 @Param 注解
          • List、Array、Set 參數(shù)
          • Map 參數(shù)
          • Java Bean 參數(shù)
          • JSON 參數(shù)

          1、匿名參數(shù)

          單個簡單類型參數(shù)

          xml 獲取的時候可以隨便寫,mybatis 會去自動處理,反正只有一個參數(shù)干脆就讓你寫啥都無所謂,不過推薦還是寫個有意義的形參:

          <!-- mapper -->
          User getUserByUsername(String userName);
          
          <!-- xml -->
          <select id="getUserByUsername" resultType="User">
              select * from t_user where user_name = #{xxoo}
          </select>

          多個簡單類型參數(shù)

          多個匿名參數(shù)的時候只能通過 mybatis 內(nèi)置的 param1、param2 按傳參順序?qū)?yīng):

          <!-- mapper -->
          List<User> selectByuserNameAndAge(String userName, Integer age);
          
          <!-- xml -->
          <select id="selectByuserNameAndAge" resultMap="BaseResultMap" >
              select *  from t_user where user_name = #{param1} and age = #{param2}
          </select>

          2、具名參數(shù)

          具名參數(shù)需要用 @Param 注解來指定

          <!-- mapper -->
          List<User> selectByuserNameAndAge(@Param("name") String userName, @Param("age") Integer age);
          
          <!-- xml -->
          <select id="selectByuserNameAndAge" resultMap="BaseResultMap" >
              select *  from t_user where user_name = #{name} and age = #{age}
          </select>

          3、List、Array、Set 參數(shù)

          List 類型參數(shù)默認值 list,Array 類型參數(shù)默認值 array,注意 Set 類型的默認值并不是 set 而是 collection,除此之外的集合默認值也是 collection,當然我們也可以用 @Param 注解來自己指定

          <!-- mapper -->
          List<User> selectByAgeList(List ages);
          
          <!-- xml -->
          <select id="selectByList" resultMap="BaseResultMap" >
              SELECT * from t_user where age in
              <foreach collection="list" open="(" separator="," close=")" item="age">
                  #{age}
              </foreach>
          </select>

          4、Map 參數(shù)

          使用 Map 參數(shù)時,可以直接用鍵名引用

          Map params = new HashMap<>();
          params.put("userName", "周小黑");
          params.put("age", 18);
          List<User> result = userMapper.selectByMapParams(params);
          
          <!-- mapper -->
          List<User> selectByMapParams(Map params);
          
          <!-- xml -->
          <select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map">
            select * from t_user where user_name = #{userName} and age = #{age}
          </select>

          5、Java Bean 參數(shù)

          和上面的 Map 比較類似,不過這里的 parameterType 要指定為對應(yīng)的 Bean 實體類型:

          <!-- mapper -->
          List<User> selectByBeans(User user);
          
          <!-- xml -->
          <select id="selectByBeans" resultMap="BaseResultMap" parameterType="User">
              select * from t_user where user_name = #{userName} and age = #{age}
          </select>

          6、JSON 參數(shù)

          和上面的 Map、Bean 參數(shù)類似,一般是直接把前端傳遞過來的 json 參數(shù)直接傳入 Mapper 中進行查詢,parameterType 為 JSONObject

          <!-- mapper -->
          List<User> selectByJSON(JSONObject params);
          
          <!-- xml -->
          <select id="selectByJSON" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject">
              select * from t_user where user_name = #{userName} and age = #{age}
          </select>

          常見屬性設(shè)置:

          • resultMap:當查詢的結(jié)果需要進行復雜的映射,例如將結(jié)果映射到具有復雜關(guān)系的對象上時,resultMap允許自定義結(jié)果集的映射規(guī)則。如果 xml 文件內(nèi)有使用 resultMap 標簽定義好結(jié)果集數(shù)據(jù),需要返回的時候直接寫 resultMap="BaseResultMap" 就行了,mybatis 會智能地自動給你映射過去。
          • resultType: 當查詢的結(jié)果可以簡單地映射到一個 POJO 對象或基本數(shù)據(jù)類型/包裝類時,使用resultType,MyBatis會嘗試自動將結(jié)果集映射到resultType指定的類型的對象上。
          • parameterType: 用于指定傳入SQL語句的參數(shù)類型,MyBatis會根據(jù)parameterType的類型,將方法參數(shù)自動轉(zhuǎn)換為SQL語句所需的類型

          常用轉(zhuǎn)義符

          XML 文件和我們常見的 HTML 類似,都是通過標簽來定義數(shù)據(jù),而尖括號本身就是表示標簽符號的開始和結(jié)束,所以在 mybatis 的 xml 文件中相關(guān)符號最好用轉(zhuǎn)義符,尤其小于符號 "<",這樣可以避免解析時報錯,常用轉(zhuǎn)義符:

          字符名稱      sql符號   轉(zhuǎn)義字符
          大于號          >           >
          小于號          <           <
          大于等于號    >=        >=
          小于等于號    <=        <=
          單引號           '            '
          雙引號          "            "

          常用 jdbcType類型對應(yīng)的 Java 類型

          天學習了JS相關(guān)的基礎(chǔ)知識,了解了JS變量、常量的聲明,以及l(fā)et、const的區(qū)別,今天學習了字符串模板,發(fā)現(xiàn)這真是一個好東西,非常實用,下面我把今天所學的內(nèi)容總結(jié)梳理一下,把重點知識跟大家分享一下,也便于日后我復習所用。

          一、模板字面量

          模板字面量是在字符串中允許插入表達式的字符串字面量,我們可以使用多行字符串和字符串的插值功能。在ES2015(即:ES6)規(guī)范的先前版本中被稱為“模板字符串”。

          • 語法

          ` string `

          ` string ${expression} `

          ` string ${expression} string `

          • 解釋

          模板字符串是增強版的字符串(Plus+),使用反引號(` `)來替代普通字符串中的單雙引號,其中${expression}表示占位符。

          注意在模板字符串中如果想使用反引號(`)需要加一個轉(zhuǎn)義符(\),即:\`

          • 普通字符串
          console.log('This is my first JS Code'); // This is my first JS Code
          • 效果圖:

          普通字符串

          • 多行字符串

          在以前的字符串中,如果我們想要多行字符串,需要用到換行符(\n),例如:

          console.log('This is my first JS Code \n' + 
          'This is my second JS Code');
          • 效果如圖:

          多行字符串

          但是,現(xiàn)在可以利用模板字符串簡化這個問題:

          console.log(`This is my first JS Code
          This is my second JS Code`);
          • 字符串中嵌入變量、表達式

          傳統(tǒng)的JS表達式需要這樣寫:

          let num = 30;
          let price = 100;
          let res = '商品數(shù)量' + num + ', 單價:' + price + '元,總計:' + num * price;

          使用上述傳統(tǒng)的表達式寫起來看著非常的亂,不直觀,有時候還容易把連接符(+)寫漏掉了,使用了ES6的模板字符串可以很好的避免這個問題:

          res = `商品數(shù)量:${num},單價:${price},總計:${num * price}`;
          console.log(res); // 商品數(shù)量:30,單價:100,總計:3000

          以上結(jié)果都輸出:

          商品數(shù)量:30,單價:100,總計:3000

          • 標簽函數(shù)

          標簽可以用函數(shù)來解析模板字符串。標簽函數(shù)的第一個參數(shù)是一個包含了字符串值的數(shù)組,剩余的參數(shù)與表達式相關(guān)。

          let num = 10;
          let price = 99;
          
          function show(strings, var1, var2) {
              console.log(strings);
              console.log(var1, var2);
          }
          
          show `商品數(shù)量:${num}單價:${price}總計:${num * price}`;
          • 輸出結(jié)果如圖:

          由上圖可以看出,strings的值是一個由多組字符串組成的數(shù)組,va1,var2的值分別為num和price的值,由此結(jié)果可以很明顯的看到,在使用標簽函數(shù)時,模板字符串會被分割成多個部分,然后傳入標簽函數(shù)中進行處理,并且是以${expression}為分隔符進行分割的。從這個結(jié)論我們可以做一個總結(jié):

          1. strings:以${}為分隔符分割得到的字符串數(shù)組;
          2. var1:模板中第一個${}的值;
          3. var2:模板中第二個${}的值;
          4. 如果還有var3,var4,var5...等變量,那么就以此類推即可。

          以上就是我所學的模板字符串的幾個常用的方法,總體感覺還不算是太難,上手很容易,根據(jù)我所學的內(nèi)容,我對模板字符串做了如下總結(jié):

          • 在表示多行字符串時,所有的空格、縮進、換行都將被保留在輸出中;
          • 表達式大括號內(nèi)(${})可以放任意的JavaScript表達式,并進行運算,以及對象屬性的引用;
          • 可以調(diào)用函數(shù);
          • 模板字符串可以嵌套。

          主站蜘蛛池模板: 国内精品视频一区二区三区| 久久er99热精品一区二区| 日本无卡码免费一区二区三区| 精品国产高清自在线一区二区三区| 在线精品视频一区二区| 免费看无码自慰一区二区| 精品免费国产一区二区| 久久精品无码一区二区三区日韩 | 一区二区3区免费视频| 中文无码精品一区二区三区| 亚洲一区二区影院| 国产视频一区在线播放| 东京热人妻无码一区二区av| 国产经典一区二区三区蜜芽| 日本一区二区三区精品视频| 伊人激情AV一区二区三区| 久热国产精品视频一区二区三区 | 免费一区二区无码东京热| 日韩精品无码一区二区三区免费 | 中文字幕一精品亚洲无线一区| 精品国产日产一区二区三区| 怡红院AV一区二区三区| 波多野结衣免费一区视频| 精品国产免费一区二区| 亚洲国产一区国产亚洲| 国产精品久久久久一区二区三区 | 91视频一区二区三区| 亚洲A∨精品一区二区三区| 日本免费一区二区在线观看| 国产精品毛片一区二区| 亚洲AV无码片一区二区三区| 在线观看午夜亚洲一区| 国产一区二区三区美女| 精品少妇ay一区二区三区 | 深夜福利一区二区| 亚洲日本va一区二区三区| 久久se精品一区精品二区| 无码日韩人妻AV一区二区三区 | 波多野结衣的AV一区二区三区| 亚洲av成人一区二区三区在线播放| 国产成人一区二区三区在线|