PHP文件大小格式化与反格式化

此代码来自drupal

  1.  
  2. define('DRUPAL_KILOBYTE', 1024);
  3.  
  4. /**
  5.  * Parses a given byte count.
  6.  *
  7.  * @param $size
  8.  *   A size expressed as a number of bytes with optional SI or IEC binary unit
  9.  *   prefix (e.g. 2, 3K, 5MB, 10G, 6GiB, 8 bytes, 9mbytes).
  10.  *
  11.  * @return
  12.  *   An integer representation of the size in bytes.
  13.  */
  14. function parse_size($size) {
  15.   $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size.
  16.   $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size.
  17.   if ($unit) {
  18.     // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by.
  19.     return round($size * pow(DRUPAL_KILOBYTE, stripos('bkmgtpezy', $unit[0])));
  20.   }
  21.   else {
  22.     return round($size);
  23.   }
  24. }
  25.  
  26. /**
  27.  * Generates a string representation for the given byte count.
  28.  *
  29.  * @param $size
  30.  *   A size in bytes.
  31.  * @param $langcode
  32.  *   Optional language code to translate to a language other than what is used
  33.  *   to display the page.
  34.  *
  35.  * @return
  36.  *   A translated string representation of the size.
  37.  */
  38. function format_size($size) {
  39.   if ($size < DRUPAL_KILOBYTE) {
  40.     return str_replace('@count bytes', '@count', $size);
  41.   }
  42.   else {
  43.     $size = $size / DRUPAL_KILOBYTE; // Convert bytes to kilobytes.
  44.     $units = array(
  45.       '@size KB',
  46.       '@size MB',
  47.       '@size GB',
  48.       '@size TB',
  49.       '@size PB',
  50.       '@size EB',
  51.       '@size ZB',
  52.       '@size YB',
  53.     );
  54.     foreach ($units as $unit) {
  55.       if (round($size, 2) >= DRUPAL_KILOBYTE) {
  56.         $size = $size / DRUPAL_KILOBYTE;
  57.       }
  58.       else {
  59.         break;
  60.       }
  61.     }
  62.     return str_replace('@size', round($size, 2), $unit);
  63.   }
  64. }
  65.  
  66. var_dump(format_size(2003330));
  67.  
  68. 输入: 1.91KB
发表在 Drupal, PHP | 留下评论

PHP filter 验证

以前要验证邮箱,ip, url等常用验证通常都是写了一个正则表达式,今天看到在drupal的includes/common.inc中有这么一个函数filter_var一查竟然是php函数,我以前竟然不知道。而且是从php5.2就开始提供了, 用法如此简单.

验证ip:

  1. // ipv4, 最后的参数可以不用。默认就是ipv4.
  2. filter_var('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
  3.  
  4. // ipv6.
  5. filter_var('fe80::6e40:8ff:fe99:dee2', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
  6.  
  7. // ipv4 或 ipv6. 只要是后面参数有多个都可以用这种表达方式.
  8. filter_var('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6);

验证邮箱

  1. filter_var('zhouitpro@gmail.com', FILTER_VALIDATE_EMAIL);

URL

  1. filter_var('http://www.baidu.com', FILTER_VALIDATE_URL);

常用的就以上几个,当然还有mac验证,浮点数和正正常难证等.
参考:http://php.net/manual/zh/function.filter-var.php
参数参考: http://php.net/manual/zh/filter.filters.validate.php

数组批量验证:

  1. $data = array(
  2.   'id' => 10085,
  3.   'url' => 'http://www.baidu.com',
  4.   'myip' => '192.168.0.22',
  5.   'myfl' => 0.23
  6. );
  7. $filter = array(
  8.   'id' => FILTER_VALIDATE_INT,
  9.   'url' => FILTER_VALIDATE_URL,
  10.   'myip' => FILTER_VALIDATE_IP | FILTER_FLAG_IPV6,
  11.   'myfl' => FILTER_VALIDATE_FLOAT
  12. );
  13. $result = filter_var_array($data, $filter);
  14.  
  15.  
  16. // 验证邮箱地址:
  17. $emails = array(
  18.   'zhouitpro@gmail.com',
  19.   '244705779@qq.com',
  20.   'helloworld',
  21. );
  22.  
  23. $filters = filter_var_array($emails, FILTER_VALIDATE_EMAIL);
  24. if(in_array(false, $filters)) {
  25.   var_dump('Email格式不正确');
  26. }
  27.  
  28. // 验证get参数
  29. $filter = array(
  30.   'id' => FILTER_VALIDATE_INT,
  31.   'callback' => FILTER_VALIDATE_URL
  32. );
  33. $filter = filter_var_array($_GET, $filter);
  34. if(in_array(null, $filter) OR in_array(false, $filter)) {
  35.   echo '参数不正确';
  36.   exit();
  37. }

更多请参考:http://php.net/manual/zh/function.filter-var-array.php

验证$_GET, $_POST, $_SERVER, $_SESSION, $_EVT, $_COOKIE数据格式

  1. /**
  2.  * $_GET => INPUT_GET
  3.  * $_POST = > INPUT_POST
  4.  * $_SERVER = INPUT_SERVER
  5.  * $_EVT = INPUT_EVT
  6.  * $_COOKE = INPUT_COOKIE
  7.  * $_SESSION = INPUT_SESSION
  8.  */
  9. var_dump(filter_input(INPUT_GET, 'test', FILTER_VALIDATE_IP));
  10.  
  11. // 以前写法.
  12. $get = isset($_GET['test']) ? $_GET['test'] : null;
  13.  
  14. // 现在可以这样写. 如果test不存在返回null.并不会报错.
  15. $get = filter_input(INPUT_GET, 'test');

参考:http://php.net/manual/zh/function.filter-input.php

发表在 PHP | 留下评论

Mac 安装Xdebug

xdebug依然是php调试神器,怎么能没有呢。。

使用pecl安装

  1. $sudo pecl install xdebug

不过这样会遇到一个错误.

downloading xdebug-2.2.3.tgz ...
Starting to download xdebug-2.2.3.tgz (250,543 bytes)
.....................................................done: 250,543 bytes
66 source files, building
running: phpize
grep: /usr/include/php/main/php.h: No such file or directory
grep: /usr/include/php/Zend/zend_modules.h: No such file or directory
grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory
Configuring for:
PHP Api Version:
Zend Module Api No:
Zend Extension Api No:
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

ERROR: `phpize' failed

做一些修复工作

  1. $sudo sh -c 'echo zend_extension=$(find /usr/lib/php/extensions -name "xdebug.so") >> $(php -qr "echo php_ini_loaded_file();") && apachectl restart'
发表在 Mac, PHP | 留下评论

HTML5 postMessage

html 5 postmessage 方法可实现不同窗体间互相通信. 可以发送对象、数组、字符串等. 可以实现多窗口变量对象共享等功能.

发送信息

  1. // 发送信息到子窗口.
  2. var iframe = $("myiframe");
  3. iframe.get(0).contentWindow.postMessage('message(string,object,array…)', 'http://yourdomain.com');
  4.  
  5. // 发送信息到父窗口
  6. parent.postmessage('message(string,object,array…)', 'http://yourdomain.com');

接收信息

  1. window.onmessage = function(evt){
  2.  var data = evt.data;
  3. }

以下是一个完整的iframe发送信息的案列.
/**index.php**/

  1. <!DOCTYPE>
  2. <html>
  3.     <head>
  4.      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.      <script type="text/javascript">
  6.        // 发送信息到子窗口.
  7.       window.onload = function() {
  8.         var postform = document.getElementById("postform");
  9.         var iframe = document.getElementById("soniframe");
  10.         postform.onsubmit = function(evt){
  11.           var message = document.getElementById("message").value;
  12.           iframe.contentWindow.postMessage(message, 'http://demo.dev');
  13.  
  14.           // 发送数组.
  15.           var testobject = new Object;
  16.           testobject.test = 1;
  17.           testobject.test2 = 2;
  18.           iframe.contentWindow.postMessage(testobject, 'http://demo.dev');
  19.  
  20.           // 发送数组.
  21.           var testarray = [1, 2];
  22.           iframe.contentWindow.postMessage(testarray, 'http://demo.dev');
  23.           return false;
  24.         }
  25.       }
  26.  
  27.       // 接收信息.
  28.       window.onmessage = function (evt) {
  29.         document.getElementById("showmsg").innerHTML = evt.data;
  30.       }
  31.     </script>
  32.     </head>
  33.   <body>
  34.       <form id="postform">
  35.         <input type="text" value="" id="message" name="message"/>
  36.         <input type="submit" value="发送"/>
  37.       </form>
  38.       <iframe style="width:100%;height:200px" id="soniframe" src="iframe.php"></iframe>
  39.   </body>
  40. </html>

/**iframe.php*/

  1. <!DOCTYPE>
  2. <html>
  3.     <head>
  4.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5.         <script type="text/javascript">
  6.           window.onmessage = function (evt) {
  7.             var data = evt.data;
  8.             if(typeof data != 'string') {
  9.               console.dir(data);
  10.             } else {
  11.               document.getElementById("showmsg").innerHTML = evt.data;
  12.             }
  13.           }
  14.  
  15.           // 发送信息到父窗口.
  16.           // parent.postMessage('test', 'http://demo.dev');
  17.         </script>
  18.     </head>
  19.     <body>
  20.         <div id="showmsg">
  21.  
  22.         </div>
  23.     </body>
  24. </html>

html5 post message

发表在 HTML5 | 留下评论

mysql导入Drupal出现no command

在windows下使用命令行导入数据库的时候出现no command错误,一堆错误的乱码

  1. mysql –password=yourpw –user=name –default-character-set=utf8 db_name <your_dump.sql
发表在 Drupal, mysql | 留下评论

Drupal hook_update_N工作原理

Drupal有一个hook叫hook_update_N(), 比如以下

  1. function mymodule_update_1() {
  2. }
  3.  
  4. function mymodule_update_100() {
  5. }
  6.  
  7. function mymodule_update_7000() {
  8. }

那是如何去执行指定的函数呢,并且后面这个数字是完全没有规律的.
打开数据库system表的schema_version字段。这个字段是保存每一个模块最后更新版本号。在更新的时候会执行大于schema_version保存的这个数字的所有函数(针对单个的模块)并且执行。

那drupal如何是如何找出来大于schema_version的所有函数呢?

首先我们以更新views模块为例子, 比如views模块中的schema_version字段当前是7000, 那么它将会执行以下几个更新函数

  1. function views_update_6009() {}
  2. function views_update_7003() {}
  3. function views_update_7020() {}
  1. // 遍历所有用户自定义的函数.
  2. $functions = get_defined_functions();
  3. $module = 'views';
  4.  
  5. $updates = array();
  6. // 遍历所有以_数字结尾的函数
  7. foreach(preg_grep('/_\d+$/', $functions['user']) as $function) {
  8.   if (preg_match('/^(?P<module>.+)_update_(?P<version>\d+)$/', $function, $matches)) {
  9.     $updates[$matches['module']][] = $matches['version'];
  10.   }
  11. }
  12.  
  13. var_export($updates);
  14. // 从而可以获取到结果为
  15. array ( 'views' => array ( 0 => '6009', 1 => '7003', 2 => '7020', ), )
  16.  
  17. // 现在就可以将获取出来的值与数据库的schema_version进行比较了.大于就执行
  18. foreach($updates['views'] as $update) {
  19.   if($update > 7000) {
  20.     $function"views_update_{$update}";
  21.     $function();
  22.      // ….. 执行更新代码
  23.   }
  24. }

参考函数: https://api.drupal.org/api/drupal/includes%21install.inc/function/drupal_get_schema_versions/7

https://api.drupal.org/api/drupal/includes%21update.inc/function/update_get_update_list/7

发表在 Drupal | 留下评论

Drupal Render工作原理

Drupal Render函数可以将数组编译成HTML. 此函数看似复杂,其实功能非常简单,就是执行hook_theme. 主要负责以下几个功能:

  • 执行theme(hook_theme), 编译单个元素,元素中的#theme或#theme_wrapper
  • 元素排序
  • 将html拼凑一起(包括前缀,后缀)
  • 编译元素附带的css/js

以编译表单为例子:

  1. function mytestform() {
  2.   $form['textfield'] = array(
  3.     '#title' => 'test input',
  4.     '#type' => 'textfield',
  5.     '#weight' => 100,
  6.   );
  7.   $form['submit'] = array(
  8.     '#title' => 'Submit',
  9.     '#value' => 'Submit',
  10.     '#type' => 'submit',
  11.     '#weight' => 2,
  12.   );
  13.   return $form;
  14. }
  15.  
  16. // 这里会把自定义的一个form变成一个可编译对象,为各个子元素潜入#theme或#theme_wrappers
  17. $form = drupal_get_form('mytestform');
  18. dpm(drupal_render($form, 'myform'));

以上为编译一个Form表单. 首先会先获取要编译的子元素,比如textfield, submit等.(一个render对象中子元素定义, 数组key前面没有”#”的则为可编译子元素)
找出子元素以后又用子元素遍历子元素执行drupal_render函数(这里属性递归,支持无限层子元素的嵌套),

在这里可以将render看成是执行hook_theme的函数。每一个可编译对象都应该会有一个#theme对象,而子元素中肯定会有一个#theme_wrappers对象。用于执行hook_theme

最后将所有的子元素生成的HTML拼凑起来并返回

发表在 Drupal | 评论关闭

Drupal weight排序工作原理

drupal元素weight排序也是使用了php函数uasort。所以如果了解了uasor也就了解了Drupal的weight.

Drupal weight排序
以前一直觉得drupal的weight排序很牛x,不知道怎么实现的(比如表单,字段)。今天有空读一下drupal的drupal_render函数.看了一下weight的工作原理
从这个函数吧, element_children这个函数是获取元素的可用元素.

  1. element_children()

函数中的一段比较简单的代码去操作了这个元素的排序.

  1. uasort($children, 'element_sort');

接着我们就可以找到element_sort函数了, 函数的内容和官方提供的案例类似(http://php.net/manual/zh/function.uasort.php#refsect1-function.uasort-examples)

  1. /**
  2.  * Function used by uasort to sort structured arrays by weight.
  3.  */
  4. function element_sort($a, $b) {
  5.   $a_weight = (is_array($a) && isset($a['#weight'])) ? $a['#weight'] : 0;
  6.   $b_weight = (is_array($b) && isset($b['#weight'])) ? $b['#weight'] : 0;
  7.   if ($a_weight == $b_weight) {
  8.     return 0;
  9.   }
  10.   return ($a_weight < $b_weight) ? -1 : 1;
  11. }
发表在 Drupal | 评论关闭

Drupal PHP PNG 图片生成错误

在Mac上面安装了php+apache+mysql以后发现上传的图片竟然无法生成。于是我检查了我的files目录的权限.也没有总是
最终追踪了drupal生成图片的代码,发现我上传的图片是png.使用了以下函数生成。我手动运行了些函数发现undefined.

  1. imagecreatefrompng('public://xxx');

https://api.drupal.org/api/drupal/modules%21system%21image.gd.inc/function/image_gd_load/7

打开drupal report发现有一个这样的警告。原来是GD库出了总是。。。。。
屏幕快照 2014-12-06 13.34.46

修复文章:stackoverflow.com/questions/26493762/yosemite-php-gd-mcrypt-installation/26505558
原来Mac需要重新编译php

发表在 PHP | 评论关闭

MAC 初始化配置

常用工具安装

https://github.com/Aaaaaashu/Mac-dev-setup

Web 开发工具

http://mallinson.ca/osx-web-development/

PHPMyadmin无法登陆

http://coolestguidesontheplanet.com/installing-phpmyadmin-on-mac-osx-10-7-lion/

发表在 Mac | 评论关闭