这是目前前端的显示结果,可供用户选择某些不处理的目录或文件使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..以下为其相关的源码:myztree.jsjQuery(document).ready(function () {
// Start: 初始化 jQuery 外掛 - zTree 的設定
var setting = {
async: {
autoParam: ['path'],
dataType: 'json',
enable: true,
otherParam: {
action: 'ztree'
},
url: ajaxurl
},
callback: {
onCheck: zTreeOnCheck,
onClick: zTreeOnClick
},
check: {
autoCheckTrigger: true,
enable: true
},
view: {
dblClickExpand: false,
showLine: false
}
}; var zTree = jQuery.fn.zTree.init(jQuery('#excluded-files'), setting, null);
// End: 初始化 jQuery 外掛 - zTree 的設定 function zTreeOnCheck(event, treeId, treeNode) {
var basedir = treeNode.path;
var checked = treeNode.checked;
var listval = JSON.parse(jQuery('#excluded-list').val());
var in_list = false;
for (var i = 0; i < listval.length; i++) {
if (listval[i]['basedir'] == basedir) {
listval[i]['checked'] = checked;
                 in_list = true;
break;
}
}
        if (!in_list) {
         listval.push({"basedir": basedir, "checked": checked});
        }
        jQuery('#excluded-list').val(JSON.stringify(listval));
}; function zTreeOnClick(event, treeId, treeNode) {
zTree.expandNode(treeNode);
};
});
ztree.php<?php
# 初始化 node 變數用於儲存所有檔案與資料夾的樹狀結構
$node = array();
# 檢查是否是第一次初始化輸出結構資訊
if ( empty( $_POST['path'] ) ) {
# 設定欲讀取資料夾為 WordPress 的上傳資料夾
$dir = sprintf( '%s/', array_pop( array_slice( wp_upload_dir(), 3, 1 ) ) );
}
# 使用者已選擇次級的資料夾
else {
# 解碼並設定已選擇的次級資料夾名稱
$dir = sprintf( '%s/', urldecode( $_POST['path'] ) );
}
# 讀取目前資料夾底下所有的資訊
$files = scandir( $dir );
# 採用自然排序法排序所有的名稱
natcasesort( $files );
# Start: 走訪本資料夾底下所有的資訊
foreach( $files as $file ) {
# 過濾無用的上層資料夾等資訊
if( $file != '.' && $file != '..' ) {
# 資料夾
if ( is_dir( $dir . $file ) ) {
# 設定本資料夾的資訊
$folder = array(
'iconSkin' => 'folder',
'isParent' => true,
'name'     => $file,
'path'     => $dir . $file
);
# 新增本資料夾至節點變數用以回傳給 zTree 處理
array_push( $node, $folder );
# 檔案
} else {
# 設定本檔案的資訊
$file = array(
'iconSkin' => sprintf( 'file_ico_docu %s', preg_replace( '/^.*\./', '', $file ) ),
'name'     => $file,
'path'     => $dir . $file
);
# 新增本檔案至節點變數用以回傳給 zTree 處理
array_push( $node, $file );
}
} else {
continue;
}
}
# End: 走訪本資料夾底下所有的資訊
# 回傳已編碼的節點資訊
echo json_encode( $node );
?>
ztree.html<tr>
<th scope="row">
<label for="excluded-files">Exclusion: </label>
</th>
<td>
<!-- Start: 使用 jQuery - ztree 輸出欲排除上傳的檔案清單 -->
<div>
<ul class="ztree" id="excluded-files"></ul>
</div>
<!-- End: 使用 jQuery - ztree 輸出欲排除上傳的檔案清單 -->
</td>
</tr>
未完成的后端处理.php<?php
function sanitize_values( $input ) {
# 檢查所欲過濾的設定值是否為一個陣列
if ( is_array( $input ) ) {
# 走訪所有的設定名稱與數值
foreach ( $input as $key => $value ) {
# 判斷設定名稱
switch ( $key ) {
# 排除上傳的檔案清單
case 'exclusion':
$list = array(
'folders' => array(),
'files'   => array()
);
$exclusions = json_decode( stripslashes( $input[$key] ), true );
if ( count( $exclusions ) > 0 ) {
foreach ( $exclusions as $exclusion ) {
switch ( is_dir ( $exclusion['basedir'] ) ) {
case true:
if ( $exclusion['checked'] )
array_push( $list['folders'], $exclusion['basedir'] );
break;
case false:
if ( $exclusion['checked'] )
array_push( $list['files'], $exclusion['basedir'] );
break;
default:
break;
}
}
}
$input[$key] = $list;
#exit( print_r( $list ) );
break;
}
}
# 回傳已過濾的設定值
return $input;
}
# 回傳錯誤
return false;
}
?>

解决方案 »

  1.   

    使用一个隐藏栏位来存放这些 JSON 数据靠谱吗 ? 因为我发现数据量满大的 ..
    没关系.尽情使用
      

  2.   


    我的确使用得很开心,但想请问 PhpNewnew 前辈 .. 该怎么去处理和储存这些数据 ?谢谢您拨冗回覆我的困扰 :-)
      

  3.   

    处理?将json 解成数组 想怎么处理就怎么处理呀
    存储?如果需要的话可以写到数据库里。如果是临时的话可以直接保存到memcache
    如果是要传递的话 直接post....
      

  4.   


    恩,谢谢您的回覆 :-)我的意思是指,这些数据会储存到数据库的表中。但我不知道该怎么去处理 "级" 的概念 ..也就是可能父层全选、子层部分选择等勾选状况。有一点像是权限树的架构 .. 但更复杂,因为目录可能是无穷级的。我想实现的处理效果是,上图中所有的文件与目录在预设设置下会被上传。但假如用户有勾选不想被上传的文件与目录等,就将之写进数据库。待其他的后端脚本在运行上传的程序时,至数据库中读取这些排除清单并做出处理。当然,若数据库写的进去了 .. 在 zTree 运行成功时也能连带先行查询再将目前用户所勾选的呈现出来。
      

  5.   

    能说说看这个是什么应用场景吗?说清楚的话可能比较有针对性的探讨。如果类似于p2p软件的共享 可能这些数据保存在客户端比较合适.例如cookie什么的,
    不过cookie也有它的局限性,会给清理,保存内容有限 等等 不过4kb似乎也够了这些文件目录是非固定的吧?
      

  6.   

    数据库最简单的方式是
    id title parentid当然还有两中,可以搜索mysql tree 等等的关键字会找到。前端用ajax吧。
      

  7.   


    是的,非固定的目录与文件。有一点像是杀毒软件的架构,它一定会有一个排除扫瞄的清单。当你没有去更改这些设置时,杀毒默认会扫瞄整个硬盘上的文件,对吧 ?但假如我从这排除清单中新增了几个文件或目录,那自然在杀毒的扫瞄程序中就会被略过了。ok, 场景回到目前的状况 ..前端显示目前目录和文件树的设计目前是可以使用的,后端 PHP 也可以接收到这些来自前端的数据。但我不知道该怎么去判断某一个文件或目录,他子父层的关系 ?可能是仅有 2012/02/Chris-150x150.jpg 的文件和 2012/03 的目录被选取;也可能是仅有 2012 整个目录和 icon/asp.asp 与 jar.jar 被选取等多种状况。目前正在看一个国外插件的范例,希望可以和大家多多讨论,谢谢你们的热心。class-file-list.php<?php
    /**
     * A class with functions the perform a backup of WordPress
     *
     * @copyright Copyright (C) 2011 Michael De Wildt. All rights reserved.
     * @author Michael De Wildt (http://www.mikeyd.com.au/)
     * @license This program is free software; you can redistribute it and/or modify
     *          it under the terms of the GNU General Public License as published by
     *          the Free Software Foundation; either version 2 of the License, or
     *          (at your option) any later version.
     *
     *          This program is distributed in the hope that it will be useful,
     *          but WITHOUT ANY WARRANTY; without even the implied warranty of
     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *          GNU General Public License for more details.
     *
     *          You should have received a copy of the GNU General Public License
     *          along with this program; if not, write to the Free Software
     *          Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
     */
    include_once( 'class-wp-backup.php' );
    class File_List { const EXCLUDED = 0;
    const INCLUDED = 1;
    const PARTIAL = 2; /**
     * A list of directories to  as partial
     * @var null
     */
    private $partial_directories = array(); /**
     * A list of files that are not allowed to be backed up
     * @var null
     */
    private $excluded_files = array(); /**
     * These files cannot be uploaded to Dropbox
     * @var array
     */
    private static $ignored_files = array( '.DS_Store', 'Thumbs.db', 'desktop.ini' ); /**
     * Construct the file list
     * @param $wpdb
     */
    public function __construct( $wpdb = null ) {
    if ( !$wpdb ) global $wpdb; $this->database = $wpdb; $file_list = get_option( 'backup-to-dropbox-file-list' );
    if ( $file_list === false ) {
    $this->partial_directories = array();
    $this->excluded_files = array();
    add_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ), null, 'no' );
    } else {
    list( $this->partial_directories, $this->excluded_files ) = $file_list;
    }
    } /**
     * Return the state of a file in the list the SQL dump is always included
     * @param  $path
     * @return bool
     */
    public function get_file_state( $path ) {
    $parent_path = dirname( $path ) . '/';
    if ( $path == dirname( ABSPATH ) . '/' ) {
    return self::PARTIAL;
    } else if ( strstr( $path, DB_NAME . '-backup.sql' ) ) {
    return self::INCLUDED;
    } else if ( in_array( $path, $this->excluded_files ) ) {
    return self::EXCLUDED;
    } else if ( in_array( $path, $this->partial_directories ) ) {
    $parent_state = $this->get_file_state( $parent_path );
    if ( $parent_state == self::INCLUDED && $parent_path != ABSPATH ) {
    $this->remove_from_partial( $path );
    $this->remove_from_excluded( $path );
    return self::INCLUDED;
    }
    return self::PARTIAL;
    } $state = $this->get_file_state( $parent_path );
    if ( $state == self::PARTIAL ) {
    $this->remove_from_partial( $path );
    $this->remove_from_excluded( $path );
    return self::INCLUDED;
    }
    return $state;
    } /**
     * @param $full_path string
     * @return string
     */
    function get_check_box_class( $full_path ) {
    $state = $this->get_file_state( $full_path );
    switch ( $state ) {
    case self::EXCLUDED:
    $class = 'checked';
    break;
    case self::PARTIAL:
    $class = 'partial';
    break;
    default: //INCLUDED so do not check
    $class = '';
    break;
    }
    return $class;
    } /**
     * Adds a file to the excluded list if it does not already exist
     * @param $file
     * @return void
     */
    private function add_to_excluded( $file ) {
    if ( !in_array( $file, $this->excluded_files ) ) {
    $this->excluded_files[] = $file;
    }
    } /**
     * Adds a file to the partial list if it does not already exist
     * @param $file
     * @return void
     */
    private function add_to_partial( $file ) {
    if ( !in_array( $file, $this->partial_directories ) ) {
    $this->partial_directories[] = $file;
    }
    } /**
     * Accepts a JSON encoded list of files and directories and adds their states to the appropriate lists
     * @param  $json_list
     * @return void
     */
    public function set_file_list( $json_list ) {
    $new_list = json_decode( stripslashes( $json_list ), true );
    foreach ( $new_list as $fl ) {
    list ( $file, $state ) = $fl;
    if ( $state == self::PARTIAL ) {
    $this->add_to_partial( $file );
    $this->remove_from_excluded( $file );
    } else if ( $state == self::EXCLUDED) {
    $this->add_to_excluded( $file );
    $this->remove_from_partial( $file );
    } else {
    $this->remove_from_excluded( $file );
    $this->remove_from_partial( $file );
    }
    }
    } /**
     * Removes a file from the excluded list if it exists
     * @param $file
     * @return void
     */
    private function remove_from_excluded( $file ) {
    if ( in_array( $file, $this->excluded_files ) ) {
    $i = array_search( $file, $this->excluded_files );
    unset( $this->excluded_files[$i] );
    }
    } /**
     * Removes a file from the partial list if it exists
     * @param $file
     * @return void
     */
    private function remove_from_partial( $file ) {
    if ( in_array( $file, $this->partial_directories ) ) {
    $i = array_search( $file, $this->partial_directories );
    unset( $this->partial_directories[$i] );
    }
    } /**
     * Saves the file list
     * @return void
     */
    public function save() {
    update_option( 'backup-to-dropbox-file-list', array( $this->partial_directories, $this->excluded_files ) );
    } /**
     * @param $dir
     * @return int
     */
    private function get_directory_state( $dir ) {
    $files = scandir( $dir );
    natcasesort( $files );
    foreach ( $files as $file ) {
    $state = $this->get_file_state( $file );
    if ( $state == self::PARTIAL || $state == self::EXCLUDED ) {
    return self::PARTIAL;
    }
    }
    return self::INCLUDED;
    } /**
     * Some files cannot be uploaded to Dropbox so check them here
     * @static
     * @param $file
     * @return bool
     */
    public static function in_ignore_list( $file ) {
    return in_array( $file, self::$ignored_files );
    }
    }
      

  8.   


    jquert-filetree.js// jQuery File Tree Plugin
    //
    // Version 1.01
    //
    // Cory S.N. LaViska
    // A Beautiful Site (http://abeautifulsite.net/)
    // 24 March 2008
    //
    // Visit http://abeautifulsite.net/notebook.php?article=58 for more information
    //
    // Usage: $('.fileTreeDemo').fileTree( options, callback )
    //
    // Options:  root           - root folder to display; default = /
    //           script         - location of the serverside AJAX file to use; default = jqueryFileTree.php
    //           folderEvent    - event to trigger expand/collapse; default = click
    //           expandSpeed    - default = 500 (ms); use -1 for no animation
    //           collapseSpeed  - default = 500 (ms); use -1 for no animation
    //           expandEasing   - easing function to use on expand (optional)
    //           collapseEasing - easing function to use on collapse (optional)
    //           multiFolder    - whether or not to limit the browser to one subfolder at a time
    //           loadMessage    - Message to display while initial tree loads (can be HTML)
    //
    // History:
    //
    // 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
    // 1.00 - released (24 March 2008)
    //
    // TERMS OF USE
    //
    // This plugin is dual-licensed under the GNU General Public License and the MIT License and
    // is copyright 2008 A Beautiful Site, LLC.
    //
    if(jQuery) (function($){ $.extend($.fn, {
    fileTree: function(o) {
    var EXCLUDED = 0;
            var INCLUDED = 1;
            var PARTIAL = 2; // Defaults
    if( !o ) var o = {};
    if( o.root == undefined ) o.root = '/';
    if( o.script == undefined ) o.script = 'jqueryFileTree.php';
    if( o.folderEvent == undefined ) o.folderEvent = 'click';
    if( o.expandSpeed == undefined ) o.expandSpeed= 500;
    if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
    if( o.expandEasing == undefined ) o.expandEasing = null;
    if( o.collapseEasing == undefined ) o.collapseEasing = null;
    if( o.multiFolder == undefined ) o.multiFolder = true;
    if( o.loadMessage == undefined ) o.loadMessage = 'Loading...'; $(this).each( function() { function showTree(c, t) {
    $(c).addClass('wait');
    $(".jqueryFileTree.start").remove();
    $.post(o.script, { action: 'file_tree', dir: t }, function(data) {
    $(c).find('.start').html('');
    $(c).removeClass('wait').append(data);
    if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing }); //Check that the list of files that we got from the server have not already
    //been included or excluded in the UI.
    $('.checkbox').each(function () {
                                var dir = escape(dirname($(this).attr('rel')));
                                if (dir == t) {
                                    var state = get_include_state($(this).attr('rel'));
                                    if (state !== false) {
                                        set_checkbox_state(this, state);
                                    }
                                }
    });
    bindTree(c);
    });
    } function bindTree(t) {
    $(t).find('LI A.tree').bind(o.folderEvent, function() {
    if( $(this).parent().hasClass('directory') ) {
    if( $(this).parent().hasClass('collapsed') ) {
    // Expand
    if( !o.multiFolder ) {
    $(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
    $(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
    }
    $(this).parent().find('UL').remove(); // cleanup
    showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
    $(this).parent().removeClass('collapsed').addClass('expanded');
    } else {
    // Collapse
    $(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
    $(this).parent().removeClass('expanded').addClass('collapsed');
    }
    } else {
    var element = $(this).parent().find('.checkbox');
    if (element.length) {
    checkbox_click(element);
    }
    }
    return false;
    }); //Bind our check box clicks
    $(t).find('ul').find('.checkbox').bind('click', function() {
    checkbox_click(this);
    }); // Prevent A from triggering the # on non-click events
    if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
    }
    // Loading message
    $(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
    // Get the initial file list
    showTree( $(this), escape(o.root) );
    }); /**
     * Updates the tri state check box based on the state hidden element passed
     * @param check_box
     */
    function set_checkbox_state(check_box, new_state) {
    new_state = parseInt(new_state);
    $(check_box).removeClass('checked');
    $(check_box).removeClass('partial');
    switch(new_state) {
    case EXCLUDED:
    $(check_box).addClass('checked');
    break;
    case PARTIAL:
    $(check_box).addClass('partial');
    break;
    default:
    break; //INCLUDED - Do nothing
    }
    } /**
     * Toggles the hidden list input with what has changed
     * @param element
     */
    function set_include_state(element) {
                    var file = $(element).attr('rel');
                    var state = get_checkbox_state(element);
    var file_tree_list = JSON.parse($('#file_tree_list').val());
    var in_list = false;
                    for (var i = 0; i < file_tree_list.length; i++) {
    if (file_tree_list[i][0] == file) {
    file_tree_list[i][1] = state;
                            in_list = true;
    break;
    }
    }
                    if (!in_list) {
                        file_tree_list.push([file, state])
                    }
    $('#file_tree_list').val(JSON.stringify(file_tree_list));
    } /**
     * Get the file state from the local list
     * @param file
     * @return int
     */
    function get_include_state(file) {
    var file_list = JSON.parse($('#file_tree_list').val());
    for (var i = 0; i < file_list.length; i++) {
    if (file_list[i][0] == file) {
    return file_list[i][1];
    }
    }
    return false;
    } /**
     * Just like PHP's dirname
     * @param path
     */
    function dirname(path) {
    return path.replace(/\/$/, '').replace(/\/[^\/]*$/, '/');
    } /**
     * Toggles the directory check box to ON, OFF or PARTIAL depending on the state of all its children.
     * @param clicked
     */
    function toggle_directory_check(clicked) {
    //Also check its directory if they are all not checked
    var checked_count = 0, total = 0;
    var clicked_parent_dir = dirname($(clicked).attr('rel'));
    $('.checkbox').each(function () {
    if (clicked_parent_dir != o.root) {
    var parent_dir = dirname($(this).attr('rel'));
    if (parent_dir == clicked_parent_dir) {
    var state = get_checkbox_state(this);
    if (state == PARTIAL || state == EXCLUDED) {
    checked_count++;
    }
    total++;
    }
    }
    }); //Now that we know that the state of all the directories children we can update the parent dir accordingly
    $('.checkbox').each(function () {
    if ($(this).attr('rel') == clicked_parent_dir) {
    if (checked_count == total) {
    set_checkbox_state(this, EXCLUDED);
      } else if (checked_count == 0) {
    set_checkbox_state(this, INCLUDED);
    } else {
    set_checkbox_state(this, PARTIAL);
    }
                            set_include_state(this);
    toggle_directory_check(this);
    }
    });
    } /**
     * Return the current state of a clicked check box
     * @param clicked
     */
    function get_checkbox_state(clicked) {
    var state = INCLUDED;
    if ($(clicked).hasClass('partial')) {
    state = PARTIAL;
    } else if ($(clicked).hasClass('checked')) {
    state = EXCLUDED;
    }
    return state;
    } /**
     * Set all the children of a directory to a state
     * @param parent
     */
    function set_directory_children(parent, state) {
    //If this is an expanded directory recursively update all its children
    if ($(parent).parent().hasClass('expanded') && $(parent).hasClass('directory')) {
    $('.checkbox').each(function () {
    if (dirname($(this).attr('rel')) == $(parent).attr('rel')) {
    set_checkbox_state(this, state);
    set_include_state(this);
    set_directory_children(this, state);
    }
    });
    }
    } /**
     * The on click function for a file check box. If the user clicks on a directory then all its open children
     * need to be updated accordingly.
     * @param clicked
     */
    function checkbox_click(clicked) {
    var state = get_checkbox_state(clicked) == EXCLUDED ? INCLUDED : EXCLUDED; set_checkbox_state(clicked, state);
    set_include_state(clicked); set_directory_children(clicked, state);
                    toggle_directory_check(clicked);
    }
    }
    });})(jQuery);