UUBlog

UUBlog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env python
#coding:utf-8

from random import randint

"""
列表筛选
生成一个有20个随机数的数组 data
从 data 列表中筛选出大于0的数字
"""

data = [randint(-100,100) for _ in xrange(10)]

print data

## 迭代
def test1(d):
s = []
for x in data:
if x >=0:
s.append(x)
return s

## 用filter
def test2(d):
return filter(lambda x:x>=0,d)

## 用列表解析
def test3(d):
return [x for x in data if x>=0]

print test1(data)
print test2(data)
print test3(data)

## 迭代最慢、列表解析最快

"""
字典的筛选
生成键值在56-100之间的随机数10个
找出大于90的数
"""

data = {x:randint(56,100) for x in xrange(1,11)}
print data

def test4(d):
return {k:v for k,v in d.iteritems() if v>=90}

print test4(data)

输出:

1
2
3
4
5
6
7
[61, -31, 2, -45, -1, 19, -41, -8, -17, 48]
[61, 2, 19, 48]
[61, 2, 19, 48]
[61, 2, 19, 48]
{1: 59, 2: 99, 3: 97, 4: 83, 5: 89, 6: 79, 7: 69, 8: 58, 9: 73, 10: 58}
{2: 99, 3: 97}

关注公众号 尹安灿

公司有块业务是靠socket提供端口供给业务查询的。

之前每次测试socket发送数据都略麻烦,所以自己用python搞了一次。

根据业务之前的逻辑,检测字段包含EOF结束读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import socket
#import codecs

#encoder = codecs.getencoder("utf-8")
senddata = '{"action":"compute","device":"ios","map":"0","start":"2017-05-19","day":"25","type":"17","orientation":"0","order_total_id":"950","store_id":"12"}EOF\n'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('dev.xxxx.net', 31))
s.send(senddata)

buffer = []
while True:
d = s.recv(65535)
if d:
buffer.append(d)
else:
break
if 'EOF' in d[-5:-1]:
break
# while True:
# d = s.recv(1024)
# if d:
# buffer.append(d)
# else:
# break
data = ''.join(buffer)
print data
s.close()

关注公众号 尹安灿

Python实现求第N位斐波那契数。迭代用来队列来保存,用其它也是可以的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/env python
#coding:utf-8
from collections import deque
import datetime

# 递归版
def fibonacci(num):
if num<=2:
return 1
else:
return fibonacci(num-1)+fibonacci(num-2)

# 迭代版
def fibonacci2(num):
s=deque()
result=0
for i in range(1,num+1):
if i<=2:
result=1
s.append(result)
else:
result=s[0]+s[1]
s.append(result)
s.popleft()
return result


n=40
print(datetime.datetime.now())
print('fibonacci(%d)=%d' % (n, fibonacci(n)))
print(datetime.datetime.now())
print('fibonacci2(%d)=%d' % (n, fibonacci2(n)))
print(datetime.datetime.now())

结果:

1
2
3
4
5
2017-05-19 18:00:52.194334
fibonacci(40)=102334155
2017-05-19 18:01:09.535270
fibonacci2(40)=102334155
2017-05-19 18:01:09.535328

递归效率还是比较底下,但是语法简明。

关注公众号 尹安灿

这前天walle部署出现了一些莫名其妙的问题。检测配置是通过的,但是部署的时候遇到前后置任务的时候总是报错。

开始以为是数据库问题,后来排查了,又以为是php执行函数exec被禁用的问题。但是并不是。

真是百思不得骑姐啊。

回想最近的改动,只有我安装过一个运维工具的agent,但是已经卸载了。

料想应该是修改了哪里的配置。

最后才定位到 /etc/profile

多了一条 #ulimit -n 204800 修改了文件符打开数量。最后我把它注释掉就好了。

至于为什么这个会影响到walle,还没深究,等找到原因再来补充。

关注公众号 尹安灿

今天给一台测试机配个环境,顺道记录下,一直觉得webtatic比官方源好用。但是老是容易忘记名字,这次就贴这里了。

安装环境所需的包

mariadb

yum groupinstall -y mariadb mairadb-client

php5.6

Repo 源

1
2
3
4
5
6
7
8
9
10
CentOS 5.X
rpm -Uvh http://mirror.webtatic.com/yum/el5/latest.rpm

CentOS 6.x
rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm

CentOS 7.X
# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
yum install epel-release
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

yum install php56w.x86_64 php56w-cli.x86_64 php56w-common.x86_64 php56w-gd.x86_64 php56w-ldap.x86_64 php56w-mbstring.x86_64 php56w-mcrypt.x86_64 php56w-mysql.x86_64 php56w-pdo.x86_64

php-fpm

yum install php56w-fpm

nginx 1.10

yum install -y nginx1w.x86_64

配置

nginx

/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
server字段里面,要配置root项,指向你网站的根目录。

另外去掉一下注释,让它支持php。里面的127.0.0.1:9000 是php-fpm所在的端口。root字段同样要指向根目录。
fastcgi_param这个要修改正确执行web根目录,否则用$document_root 然后配置好root路径就好。
root /www/web;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;

yum包安装的,它用户都给你创建好和修改好了。

php-fpm

其实user和group用默认的也是没问题的。但是为了以后方便自定义点,我用了一个叫www的账户

1
2
3
# groupadd www-data
# useradd -g www-data www-data

/etc/php-fpm.d/www.conf

1
2
3
user=www
group=www

为了更好的性能,建议对nginx.conf 配置一下worker的数量,php-fpm 配置一下池,常驻进程数量。

mysql 先运行mysql_secure_installation这个脚本来改一下root密码,关闭远程连接和删除测试数据库之类的东西。

启动服务

1
2
3
# systemctl start  php-fpm mariadb nginx
# systemctl enable php-fpm mariadb nginx

参考资料

关注公众号 尹安灿

异常处理

Python 的异常接管和很多程序的都差不多,尤其是Pascal。

常见的异常类型有

1
2
3
4
5
6
ImportError:an import fails 导入失败,一般导入了无效的模块
IndexError:a list is indexed with an out of range number 超出列表最大长度
NameError:an unknown variable is used 未定义的变量
SyntaxError:the code can't be parsed properly 不能匹配的语法
TypeError:a funxtion is called on a value of an inappropriate type 错误的类型
ValueError:a function is called on a value of the correct type but with an inappropriate value 错误的值

异常的接管

1
2
3
4
try:
# do sth
except <具体要接管的错误类型,留空则接管所有异常>:
# 异常处理部分

比如除以0的时候都会抛出一个ZeroDivisionError异常。

而接管异常处理示例

1
2
3
4
5
try:
result = 1 / 0
except ZeroDivisionError:
print('error')

又或者留空,默认接管所有异常。

1
2
3
4
5
try:
result = 1 / 0
except:
print('error')

又或者使用多个except接管多个不同类型的异常。

1
2
3
4
5
6
7
try:
result = 1 / 0
except ZeroDivisionError:
print('ZeroDivisionError')
except IOError:
print('IOError')

以上只是列举了异常类型的小部分

异常类型列表

如果想查看更多异常类型,可以导入exceptions模块,用dir查看。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
In [1]: import exceptions

In [2]: dir(exceptions)
Out[2]:
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'BufferError',
'BytesWarning',
'DeprecationWarning',
'EOFError',
'EnvironmentError',
'Exception',
'FloatingPointError',
'FutureWarning',
'GeneratorExit',
'IOError',
'ImportError',
'ImportWarning',
'IndentationError',
'IndexError',
'KeyError',
'KeyboardInterrupt',
'LookupError',
'MemoryError',
'NameError',
'NotImplementedError',
'OSError',
'OverflowError',
'PendingDeprecationWarning',
'ReferenceError',
'RuntimeError',
'RuntimeWarning',
'StandardError',
'StopIteration',
'SyntaxError',
'SyntaxWarning',
'SystemError',
'SystemExit',
'TabError',
'TypeError',
'UnboundLocalError',
'UnicodeDecodeError',
'UnicodeEncodeError',
'UnicodeError',
'UnicodeTranslateError',
'UnicodeWarning',
'UserWarning',
'ValueError',
'Warning',
'ZeroDivisionError',
'__doc__',
'__name__',
'__package__']

对象安全释放

这个和许多语言都有点类似。一般在发生异常的时候,执行就被中断了。而有些被打开的数据有可能会被丢失。

尤其是用open打开文件的时候,很有可能导致内容丢失。所以为了让代码在出现异常的时候,一样能执行特定的代码。比如释放对象,安全关闭文件等。就有了 try ... finally语句。

1
2
3
4
try:
result = 1 / 0
finally:
print('still working.')

比如常见安全关闭文件

1
2
3
4
5
try:
f = open('test.txt','wb')
result = 1 / 0
finally:
f.close()

不过对于安全打开关闭文件,一般更推荐的做法是用with

1
2
3
with open("test.txt","wb") as f:
result = 1 / 0
#or do sth.

提起/引出异常 raise

有时候在处理潜在有问题的代码的时候,你希望主动引出一个异常,可以用raise语句。

比如引出一个 ValueError

raise ValueError

异常带参数描述异常

raise ValueError('值错误')

断言assert

断言使用,可能都是用于自己调试程序的时候才会用到。

assert 1!=1 当后面表达式不为True的时候,就会引发AssertionError错误。

关注公众号 尹安灿

需要将json的数据,按program属性的数组大小进行排序。Python实现特别轻松,主要在交换值方面轻松,以前用Delphi代码量起码是这个两倍。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#coding:utf-8
import json

jsonraw='[{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"19","orientation_name":"东","map_name":"格局三","start":"2017-05-09","floor_name":"东2楼","number":"2009","map_id":"16","days":"25","end":"2017-06-02","floor_id":"64","id":"104"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局三","start":"2017-05-09","floor_name":"东2楼","number":"2011","map_id":"16","days":"25","end":"2017-06-02","floor_id":"64","id":"105"}]},{"scores":0,"program":[{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局二","start":"2017-05-09","floor_name":"东3楼","number":"3009","map_id":"15","days":"25","end":"2017-06-02","floor_id":"65","id":"106"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"19","orientation_name":"东","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5005","map_id":"15","days":"25","end":"2017-06-02","floor_id":"67","id":"108"}]},{"scores":0,"program":[{"type_name":"普通房","type_id":"16","orientation_id":"22","orientation_name":"南","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5006","map_id":"15","days":"25","end":"2017-06-02","floor_id":"67","id":"109"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5007","map_id":"15","days":"25","end":"2017-06-02","floor_id":"67","id":"110"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"23","orientation_name":"北","map_name":"格局三","start":"2017-05-09","floor_name":"东5楼","number":"5008","map_id":"16","days":"25","end":"2017-06-02","floor_id":"67","id":"111"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5009","map_id":"15","days":"25","end":"2017-06-02","floor_id":"67","id":"112"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"19","orientation_name":"东","map_name":"格局三","start":"2017-05-09","floor_name":"东2楼","number":"2009","map_id":"16","days":"22","end":"2017-05-30","floor_id":"64","id":"104"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局三","start":"2017-05-09","floor_name":"东2楼","number":"2011","map_id":"16","days":"22","end":"2017-05-30","floor_id":"64","id":"105"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局二","start":"2017-05-09","floor_name":"东3楼","number":"3009","map_id":"15","days":"22","end":"2017-05-30","floor_id":"65","id":"106"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"19","orientation_name":"东","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5005","map_id":"15","days":"22","end":"2017-05-30","floor_id":"67","id":"108"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"普通房","type_id":"16","orientation_id":"22","orientation_name":"南","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5006","map_id":"15","days":"22","end":"2017-05-30","floor_id":"67","id":"109"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5007","map_id":"15","days":"22","end":"2017-05-30","floor_id":"67","id":"110"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"23","orientation_name":"北","map_name":"格局三","start":"2017-05-09","floor_name":"东5楼","number":"5008","map_id":"16","days":"22","end":"2017-05-30","floor_id":"67","id":"111"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]},{"scores":0,"program":[{"type_name":"标准间","type_id":"15","orientation_id":"21","orientation_name":"西","map_name":"格局二","start":"2017-05-09","floor_name":"东5楼","number":"5009","map_id":"15","days":"22","end":"2017-05-30","floor_id":"67","id":"112"},{"type_name":"普通房","type_id":"16","orientation_id":"19","orientation_name":"东","map_name":"格局11","start":"2017-05-31","floor_name":"东6楼","number":"6007","map_id":"14","days":"3","end":"2017-06-02","floor_id":"68","id":"114"}]}]'

jsonarr=json.loads(jsonraw)

arrlen = len(jsonarr)

for i in range(0,arrlen):
for j in range(i+1,arrlen):
if len(jsonarr[i]['program']) > len(jsonarr[j]['program']):
jsonarr[i],jsonarr[j] = jsonarr[j], jsonarr[i]

print jsonarr

关注公众号 尹安灿

要实现对括号对的匹配。

假如不能双双配对,就是不合适的。举个例子

1
2
3
4
5
6
正确
'sd{sfsfs}[(s)]'
'[{()}]'

不正确
'[[]{()}'

思路就是用一个栈存储匹配到的左括号,匹配到右括号的话,就和栈顶的数据对比。因为两个括号的ASCII码,一般右括号总比左括号大1或者2.通过判断差值是否在这个区间,基本可以确定。匹配到一对括号,便消除一个。到最后如果栈为空,就是合格的。反之,不为空就是不合格的。

实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/python
#coding:utf-8

leftChar=['{','[','(']
rightChar=['}',']',')']

def check_format(sPath):
s=[]
for x in sPath:
if x in leftChar:
s.append(x)
if x in rightChar:
if s:
if abs(ord(x)-ord(s[-1]))<=2:
s.pop()
else:
s.append(x)
else:
s.append(x)
if s:
print u"不合格"
else:
print u"合格"

结果如下

1
2
3
4
check_format('sd{sfsfs}[(s)]')
合格
check_format('[[]{()}')
不合格

关注公众号 尹安灿

很多数据都做了备份,而且全都用脚本完成。并定时下载一份回我们本地,等于多多点异地备份了,避免被一锅端了的情况。

像代码,这个是分发的,而且开发人手一份,这个就不备份了。用户静态数据也都定时做了rsync同步备份,压缩保存。

连测试环境的数据库都做了自动的MySQL逻辑备份。唯独线上环境,存在RDS中的MySQL数据库,虽然有RDS定时备份实例,但是不经常上去下载一份保存回本地你是不得安心的。

这万一被盗号了呢。。。岂不是辛辛苦苦几十年,一删回到解放前。

本来是可以用mysqldump -h 远程IP 这样备份的。但是RDS可能是防止脱裤,搞了限制。所以,往日都是我自己上阿里云官网,手动点击下载备份。

为了减少这一部分的重复劳动,我决定用阿里云的SDK搞一个自动下载实例。

以为会遇到很多麻烦,没想到SDK封装得还不错,使用异常简单。

步骤分为如下几步

  1. 安装阿里云API封装的Python SDK

    里面几乎有阿里云所有产品的SDK,这给我们定制自己的工具提供了很大的便利。
    这里我们要用的是RDS相关的功能,所以 sudo pip install aliyun-python-sdk-rds就行了。

  2. 申请访问API需要用的Access Key

    最好先新建RAM账号,再申请AK。

  3. 编码

整个备份逻辑很简单,就是查看指定日期区间备份列表,获取备份信息。然后下载备份。

主要用到SDK DescribeBackupsRequest 这个类。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from aliyunsdkcore import client
#from aliyunsdkrds.request.v20140815 import DescribeRegionsRequest
from aliyunsdkrds.request.v20140815 import DescribeBackupsRequest
import json
import requests
import datetime
#import time

saveRoot='/home/phan/backups/' #设置备份根目录

# 下载链接
def downLink(url,dateStr):
downFile = requests.get(url)
# 设置备份目录
savePath = '%s%s.tar.gz'%(saveRoot,dateStr)
with open(savePath,'wb') as backup_file:
backup_file.write(downFile.content)

# 获取今日和明日的日期
today=datetime.date.today();
yesterday=datetime.date.today() - datetime.timedelta(1)

clt = client.AcsClient('你的AK','你的ASK','cn-shenzhen') #这里的地区ID非必须的

request = DescribeBackupsRequest.DescribeBackupsRequest()
## 以下请求的参数都是必须的 尤其实例名和查询区间
request.set_accept_format('json')
request.set_action_name('DescribeBackups')
request.set_DBInstanceId('rm-xxxxxxxxxxx') # 你的实例ID
request.set_StartTime('%sT00:00Z'%(yesterday))
request.set_EndTime('%sT00:00Z'%(today))
result = clt.do_action_with_exception(request)
## 下载RDS备份
if result:
json_rds = json.loads(result)
if json_rds['Items']['Backup'][0]['BackupStatus']=='Success':
downLink(json_rds['Items']['Backup'][0]['BackupDownloadURL'],today)

print u"数据库备份完成"

至此,加入crontab,备份基本全自动了。

参考资料

Aliyun Python SDK
Aliyun RDS Help

关注公众号 尹安灿

有这么一个需求,需要根据svn生成的版本之间差异的文件列表,生成一个treeview。

数据样本如下:

1
2
3
4
5
6
7
8
9
10
11
$defaultStr = [
'Public/images/list/order.png',
'Public/images/list/reverse.png',
'Application/Crm/View/ReturnWork/visitRecord.html',
'Application/Crm/View/ReturnWork/myVisit.html',
'Application/Crm/View/ReturnWork/memberReturn.html',
'Application/Crm/View/ReturnWork/fitReturn.html',
'Application/Crm/View/ReturnWork/emergencReturn.html',
'Application/Crm/View/UserManagement/user_list.html',
'Application/Crm/View/UserManagement/add_maternal.html',
'ver.txt'];

思路如下,先根据 / 符号拆分路径成数组,拼凑tree数组。最后根据tree数组递归生成json数组。

生成数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$tree=array();

function pushNode($subtree,$name){
if(!empty($name)){
$tmpname=end($name);
if(!array_key_exists(end($name),$subtree)){
$subtree[$tmpname]=array();
}
array_pop($name);
$subtree[$tmpname]=pushNode($subtree[$tmpname],$name);
return $subtree;
}
}

for($i=0;$i<count($defaultStr);$i++){
$path_str=array_reverse(explode('/', $defaultStr[$i]));
$tree = pushNode($tree,$path_str);
}
var_dump($tree);

生成类似如下的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

array(3) {
["Public"]=>
array(1) {
["images"]=>
array(1) {
["list"]=>
array(2) {
["order.png"]=>
NULL
["reverse.png"]=>
NULL
}
}
}
["Application"]=>
array(1) {
["Crm"]=>
array(1) {
["View"]=>
array(2) {
["ReturnWork"]=>
array(5) {
["visitRecord.html"]=>
NULL
["myVisit.html"]=>
NULL
["memberReturn.html"]=>
NULL
["fitReturn.html"]=>
NULL
["emergencReturn.html"]=>
NULL
}
["UserManagement"]=>
array(2) {
["user_list.html"]=>
NULL
["add_maternal.html"]=>
NULL
}
}
}
}
["ver.txt"]=>
NULL
}

递归生成树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//递归生成树
function makeJsonTree($tree){
$json=[];
if(!empty($tree)){
foreach ($tree as $key => $value){
$jsonNode=[];
$jsonNode['text']=$key;
if($value!==null){
$jsonNode['nodes']=makeJsonTree($value);
}
array_push($json,$jsonNode);
}
}
return $json;
}

生成最终符合bootstrap treeview的格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
[
{
text: "Public",
nodes: [
{
text: "images",
nodes: [
{
text: "list",
nodes: [
{
text: "order.png"
},
{
text: "reverse.png"
}
]
}
]
}
]
},
{
text: "Application",
nodes: [
{
text: "Crm",
nodes: [
{
text: "View",
nodes: [
{
text: "ReturnWork",
nodes: [
{
text: "visitRecord.html"
},
{
text: "myVisit.html"
},
{
text: "memberReturn.html"
},
{
text: "fitReturn.html"
},
{
text: "emergencReturn.html"
}
]
},
{
text: "UserManagement",
nodes: [
{
text: "user_list.html"
},
{
text: "add_maternal.html"
}
]
}
]
}
]
}
]
},
{
text: "ver.txt"
}
]

关注公众号 尹安灿

0%