CodeSky 代码之空

随手记录自己的学习过程

PHP 计算两个文件的相对路径

2014-01-25 21:16分类: PHP评论: 1

没错这是我目前的得意之作之一,还特地写了CSS,虽然不怎么好…… 所谓使尽浑身解数……

打了草稿,嗯虽然估计过会儿我自己都要看不懂了。(思路,{}的部分在写下来之后发现了共同点就合并了)

删除 . 和空白数组 比较相同元素,到不同时中断 统计b还有多少元素 不同元素的多少决定了..个数 按序输出不同元素 count数组中元素的大小,取小的那一个作为比较次数 比较一个元素删除一个元素 {如果比完完全符合 则如果b小 返回a剩余元素 b大 返回差集数组计算元素数返回../数 如果不完全符合,则b剩余元素替换为..后加上a剩余元素} b剩余元素变为../后输出a剩余元素 如果输入文件名a/..

演示

为了找相对路径规律还写了不同的……

$a = '/a/b/c/d/e.png' $b = '/a/b/c' 相对路径:/d/e

$a = '/a/b/c' $b = '/a/b/c/d' 相对路径 ../

$a = '/a/b/c/d/' $b = '/a/b/12/34/' 相对路径 ../../c/d

$a = '/a/b/d' $b = '/a/b/c/d' 相对路径 ../../d

$a = 'a/b/d/e' $b = 'a/b/c' 相对路径 ../d/e

我们分解下面来说明。

1		body {
2			background: #F5F5F5;
3		}
4
5		div {
6			width: 400px;
7			height: 250px;
8			position: absolute;
9			left: 50%;
10			top: 50%;
11			margin-left: -150px;
12			margin-top: -125px;
13			background: #eee;
14			border-radius: 5px;
15			box-shadow: 0 1px 1px;
16		}
17
18		form {
19			width: 280px;
20   			margin: 0 auto;
21		}
22
23		h1 {
24			text-align: center;
25		}
26
27		input[type="text"] {
28			width: 280px;
29		}
30
31		input[type="text"]:hover {
32			box-shadow: 0 0 5px #000;
33		}
34
35		input[type="submit"] {
36			width: 40%;
37			position: relative;
38		}
39
40		p {
41			float: none;
42			text-align: center;
43
44		}
45

CSS部分我们这次定义了input的样式,可以看出格式是input[type="text"],另外使用了刚学会的box-shadow,详情在:Box-shadow实现常用阴影效果

这次的居中模型使用了:CSS几个竖直与水平居中盒子模型的第一种(当然好像不大会用啊OTZ)

1<label>保留文件名:<input type="checkbox" name="file_name" value="yes"></label>
2

form中使用了label,关于这点可以围观:表单input增强用户体验(label和placeholder)

1			if(!empty($_POST['shot'])) {
2				$problem = FALSE;
3
4				if(empty($_POST['routea'])) {
5					echo '请输入第一个路径';
6					$problem = TRUE;
7				}
8
9				if(empty($_POST['routeb'])) {
10					echo '请输入第二个路径';
11					$problem = TRUE;
12				}
13
14				if(!$problem) {
15
16					$a = explode('/', trim($_POST['routea']));
17					$b = explode('/', trim($_POST['routeb']));
18					
19					$check1 = check_route('..', $a);
20					$check2 = check_route('..', $b);
21					$a = $check1[0];
22					$b = $check2[0];
23					$pass = ($check1[1] && $check2[1]);
24					
25					if ($pass) {
26						$a = clean_empty_element('', $a);
27						$b = clean_empty_element('', $b);
28						$array1 = search_and_clean('.', $a);
29						$array2 = search_and_clean('.', $b);
30						$a = $array1[0];
31						$b = $array2[0];
32
33						$counta = count($a);
34						$countb = count($b);
35
36						$count = ($counta < $countb) ? $counta : $countb;
37
38						for ($i=0; $i < $count ; $i++) { 
39							if ($a[$i] == $b[$i]) {
40								unset($a[$i]);
41								unset($b[$i]);
42							} else {
43								break;
44							}
45						}
46
47						$route = '';
48
49						$countpoint = count($b);
50
51						for ($i=0; $i < $countpoint; $i++) { 
52							$route .= '../';
53						}
54
55
56						if (!empty($a)) {
57							foreach ($a as $key => $value) {
58								$route .= $value . '/';
59							}
60						}
61
62						if(!empty($_POST['file_name'])) {
63							if (isset($array1[1])) {
64								$route .= $array1[1];
65							}
66						}
67
68						if(!empty($route)) {
69							echo '相对路径为' . $route;
70						} else {
71							echo '完全一样哟';
72						}
73					} else {
74						echo '请输入正确的路径';
75					}
76
77				}
78			}
79
80			/* 清除字符串与指定字符串相同的数组元素	*/
81			function clean_empty_element($str, $array) {
82				foreach ($array as $key => $value) {
83					if ($array[$key] == $str) {
84						unset($array[$key]);
85					}
86				}
87				$array = array_values($array);
88				return $array;
89			}
90
91			/* 清除带指定字符的数组元素*/
92			function search_and_clean($str, $array) {
93				$file = NULL;
94				foreach ($array as $key => $value) {
95					if (strpos($value, $str)) {
96						$file = $value;
97						unset($array[$key]);
98					}
99				}
100				$array = array_values($array);
101				return array($array, $file);
102			}
103
104			function check_route($str, $array) {
105				$counter = 0;
106				$pass = TRUE;
107				foreach ($array as $key => $value) {
108					if ($value == $str) {
109						$counter++;
110						$array[$key] = '';
111						if (isset($array[$key - ($counter * 2)])) {
112							for ($i=0; $i <= ($counter * 2); $i++) { 
113								$array[$key - $i] ='';
114							}
115						} else {
116							$pass = FALSE; 
117						}
118					} else {
119						$counter = 0;
120					}
121				}
122
123				return array($array, $pass);
124			}
125

php的部分相当长…… 首先毫无疑问验证表单是否提交,然后为了避免用户误输入空格,采取了trim(),作用是消除两端空格(文件夹里有空格很正常吧……) 扩展阅读:http://www.php.net/manual/zh/function.trim.php 然后再次使用explode()拆分字符串为数组,在PHP检查IP是否在指定范围内中曾经提到过。

接着检查与简化路径(避免用户输入复杂路径)(这是第二版添加上的T T我根本想不到路径会那么写啊)。

然后清除数组中空白元素和带文件名后缀的元素,之后我们使用了一个三元运算符:$count = ($counta < $countb) ? $counta : $countb;,因为我们的循环次数取小。

思路基本上同前面写的草稿,发现不同之后用break立即跳出循环。

依次连接字符串。

最后根据选项选择末尾是否要添加文件名。

这里我写了三个很有用的函数,具有推广性,应此在函数中变量为两个,一个是字符串,另一个是数组名。

1			/* 清除字符串与指定字符串相同的数组元素	*/
2			function clean_empty_element($str, $array) {
3				foreach ($array as $key => $value) {
4					if ($array[$key] == $str) {
5						unset($array[$key]);
6					}
7				}
8				$array = array_values($array);
9				return $array;
10			}
11

如果发现了和指定字符串完全相同的数组元素,就unset()释放(销毁)它,全部循环完毕之后用array_value()重新建立索引。

1			/* 清除带指定字符的数组元素*/
2			function search_and_clean($str, $array) {
3				$file = NULL;
4				foreach ($array as $key => $value) {
5					if (strpos($value, $str)) {
6						$file = $value;
7						unset($array[$key]);
8					}
9				}
10				$array = array_values($array);
11				return array($array, $file);
12			}
13
14

这里使用了strpos(),作用是返回字符串中指定字符串的位置,这里我们输入了一个'.',又恰好如果是..的话位置是0,布尔值是FALSE,被排除在外了,所以如果想要算上所有的位置,还是得用isset()一类的。同样的销毁,重建数组。

我们这里还设定了一个$file,为了便于输出文件名,实现把$file储存,但$file不存在导出会报错,所以设定了一个NULL

返回不能返回多值,只能以数组形式返回了,关于返回值,在PHP变量命名规则与范围提及。

1			function check_route($str, $array) {
2				$counter = 0;
3				$pass = TRUE;
4				foreach ($array as $key => $value) {
5					if ($value == $str) {
6						$counter++;
7						$array[$key] = '';
8						if (isset($array[$key - ($counter * 2)])) {
9							for ($i=0; $i <= ($counter * 2); $i++) { 
10								$array[$key - $i] ='';
11							}
12						} else {
13							$pass = FALSE; 
14						}
15					} else {
16						$counter = 0;
17					}
18				}
19
20				return array($array, $pass);
21			}
22

这是我写过最神奇的东西,曾经想过unset()加指针移动,未果,报错,于是就产生了这货,这货配合第一个函数使用就能达到简化目录的效果,它的拓展意义不大,主要是检索$str连续出现数量,然后成双替代,扩宽范围,如果下一个不是$str的时候把计数器清零,另外如果目录../出现太多,则会有相应提示。

完整版源代码:

1<!DOCTYPE html>
2<html>
3<head>
4	<meta charset="utf-8">
5	<style type="text/css">
6		body {
7			background: #F5F5F5;
8		}
9
10		div {
11			width: 400px;
12			height: 250px;
13			position: absolute;
14			left: 50%;
15			top: 50%;
16			margin-left: -150px;
17			margin-top: -125px;
18			background: #eee;
19			border-radius: 5px;
20			box-shadow: 0 1px 1px;
21		}
22
23		form {
24			width: 280px;
25   			margin: 0 auto;
26		}
27
28		h1 {
29			text-align: center;
30		}
31
32		input[type="text"] {
33			width: 280px;
34		}
35
36		input[type="text"]:hover {
37			box-shadow: 0 0 5px #000;
38		}
39
40		input[type="submit"] {
41			width: 40%;
42			position: relative;
43		}
44
45		p {
46			float: none;
47			text-align: center;
48
49		}
50
51	</style>
52	<title>Route</title>
53</head>
54<body>
55	<div>
56		<h1>相对路径生成器</h1>
57		<p>将生成第二个文件相对于第一个的相对路径</p>
58		<form action="route.php" method="post">
59			<input type="text" name="routea" placeholder="输入第一个文件路径如/a/b/c/d/e.php"><br/>
60			<input type="text" name="routeb" placeholder="输入第二个文件路径如/a/b/12/34/c.php"><br/>
61			<label>保留文件名:<input type="checkbox" name="file_name" value="yes"></label>
62			<input type="hidden" name="shot" value="shot">
63			<input type="submit" value="运算">
64		</form>
65		<p>
66		<?php
67			if(!empty($_POST['shot'])) {
68				$problem = FALSE;
69
70				if(empty($_POST['routea'])) {
71					echo '请输入第一个路径';
72					$problem = TRUE;
73				}
74
75				if(empty($_POST['routeb'])) {
76					echo '请输入第二个路径';
77					$problem = TRUE;
78				}
79
80				if(!$problem) {
81
82					$a = explode('/', trim($_POST['routea']));
83					$b = explode('/', trim($_POST['routeb']));
84					
85					$temp1 = check_protocol('http:', $a);
86					$temp2 = check_protocol('http:', $b);
87					$protocol_a_http = $temp1[1];
88					$protocol_b_http = $temp2[1];
89					$a = $temp1[0];
90					$b = $temp2[0];
91
92					$temp1 = check_protocol('file:', $a);
93					$temp2 = check_protocol('file:', $b);
94					$protocol_a_file = $temp1[1];
95					$protocol_b_file = $temp2[1];
96					$a = $temp1[0];
97					$b = $temp2[0];
98
99					$temp1 = check_protocol('ftp:', $a);
100					$temp2 = check_protocol('ftp:', $b);
101					$protocol_a_ftp = $temp1[1];
102					$protocol_b_ftp = $temp2[1];
103					$a = $temp1[0];
104					$b = $temp2[0];
105					
106					
107					$pass4 = TRUE;
108					
109					if ($protocol_a_http || $protocol_b_http || $protocol_a_file || $protocol_b_file || $protocol_a_ftp || $protocol_b_ftp) {
110						switch ($protocol_a_http || $protocol_b_http || $protocol_a_file || $protocol_b_file || $protocol_a_ftp || $protocol_b_ftp) {
111							case ($protocol_a_http&&$protocol_b_http):
112								if($a[1] !== $b[1]) {
113									echo '你输入的域名不相同<br/>';
114									$pass4 = FALSE;
115								}
116								break;
117							case ($protocol_a_ftp&&$protocol_b_ftp):
118								if($a[1] !== $b[1]) {
119									echo '你输入的FTP地址不相同<br/>';
120									$pass4 = FALSE;
121								}
122								break;
123							case ($protocol_a_file&&$protocol_b_file):
124								break;
125							default:
126								echo "协议不一致<br/>";
127								$pass4 = FALSE;
128								break;
129						}
130					}
131					
132					$check1 = check_route('..', $a);
133					$check2 = check_route('..', $b);
134					$a = $check1[0];
135					$b = $check2[0];
136					$pass1 = ($check1[1] && $check2[1]);
137					$pass2 = (search(' ', $a) && search(' ', $b));
138					$pass3 = (search('.', $a) && search('.', $b));
139					
140					if ($pass1 && $pass2 && $pass3 && $pass4) {
141						$a = clean_empty_element('', $a);
142						$b = clean_empty_element('', $b);
143						$array1 = search_and_clean_last('.', $a);
144						$array2 = search_and_clean_last('.', $b);
145						$a = $array1[0];
146						$b = $array2[0];
147
148						$counta = count($a);
149						$countb = count($b);
150
151						$count = ($counta < $countb) ? $counta : $countb;
152
153						for ($i=0; $i < $count ; $i++) { 
154							if ($a[$i] == $b[$i]) {
155								unset($a[$i]);
156								unset($b[$i]);
157							} else {
158								break;
159							}
160						}
161
162						$route = '';
163
164						$countpoint = count($b);
165
166						for ($i=0; $i < $countpoint; $i++) { 
167							$route .= '../';
168						}
169
170
171						if (!empty($a)) {
172							foreach ($a as $key => $value) {
173								$route .= $value . '/';
174							}
175						}
176
177						if(!empty($_POST['file_name'])) {
178							if (isset($array1[1])) {
179								$route .= $array1[1];
180							}
181						}
182
183						if(!empty($route)) {
184							echo '相对路径为' . $route;
185						} else {
186							echo '完全一样哟';
187						}
188					} else {
189						echo '请输入正确的路径';
190					}
191
192				}
193			}
194
195			/* 检查协议	*/
196			function check_protocol($protocol, $array) {
197				$check = FALSE;
198				if ($array[0] === $protocol) {
199					$check = TRUE;
200					unset($array[0]);
201					$array = array_values($array);
202				}
203				return array($array, $check);
204
205			}
206
207			/* 检查数组中是否含指定字符串	*/
208			function search($str, $array) {
209				$pass = TRUE;
210				foreach ($array as $key => $value) {
211					if ($value == $str) {
212						$pass = FALSE;
213						break;
214					}
215				}
216				return $pass;
217			}
218
219			//只检查最后一个的函数 其他当作文件名来处理
220			function search_and_clean_last($str, $array) {
221				$file = NULL;
222				$counter = count($array);
223				if(strpos($array[$counter - 1], $str)) {
224					$file = $array[$counter - 1];
225					unset($array[$counter - 1]);
226				}
227				$array = array_values($array);
228				return array($array, $file);
229			}
230
231			/* 清除字符串与指定字符串相同的数组元素	*/
232			function clean_empty_element($str, $array) {
233				foreach ($array as $key => $value) {
234					if ($array[$key] == $str) {
235						unset($array[$key]);
236					}
237				}
238				$array = array_values($array);
239				return $array;
240			}
241
242			/* 清除带指定字符的数组元素*/
243			function search_and_clean($str, $array) {
244				$file = NULL;
245				foreach ($array as $key => $value) {
246					if (strpos($value, $str)) {
247						$file = $value;
248						unset($array[$key]);
249					}
250				}
251				$array = array_values($array);
252				return array($array, $file);
253			}
254
255			function check_route($str, $array) {
256				$counter = 0;
257				$pass = TRUE;
258				foreach ($array as $key => $value) {
259					if ($value == $str) {
260						$counter++;
261						$array[$key] = '';
262						if (isset($array[$key - ($counter * 2)])) {
263							for ($i=0; $i <= ($counter * 2); $i++) { 
264								$array[$key - $i] ='';
265							}
266						} else {
267							$pass = FALSE; 
268						}
269					} else {
270						$counter = 0;
271					}
272				}
273
274				return array($array, $pass);
275			}
276
277
278		?>
279		</p>
280	</div>
281
282</body>
283</html>
284

评论 (1)

kn0072014年1月29日 10:31

好长好长