Verzeichnisstruktur phpBB-3.1.0
- Veröffentlicht
- 27.10.2014
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
FileProfilerStorage.php
001 <?php
002 /*
003 * This file is part of the Symfony package.
004 *
005 * (c) Fabien Potencier <fabien@symfony.com>
006 *
007 * For the full copyright and license information, please view the LICENSE
008 * file that was distributed with this source code.
009 */
010
011 namespace Symfony\Component\HttpKernel\Profiler;
012
013 /**
014 * Storage for profiler using files.
015 *
016 * @author Alexandre Salomé <alexandre.salome@gmail.com>
017 */
018 class FileProfilerStorage implements ProfilerStorageInterface
019 {
020 /**
021 * Folder where profiler data are stored.
022 *
023 * @var string
024 */
025 private $folder;
026
027 /**
028 * Constructs the file storage using a "dsn-like" path.
029 *
030 * Example : "file:/path/to/the/storage/folder"
031 *
032 * @param string $dsn The DSN
033 *
034 * @throws \RuntimeException
035 */
036 public function __construct($dsn)
037 {
038 if (0 !== strpos($dsn, 'file:')) {
039 throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn));
040 }
041 $this->folder = substr($dsn, 5);
042
043 if (!is_dir($this->folder)) {
044 mkdir($this->folder, 0777, true);
045 }
046 }
047
048 /**
049 * {@inheritdoc}
050 */
051 public function find($ip, $url, $limit, $method, $start = null, $end = null)
052 {
053 $file = $this->getIndexFilename();
054
055 if (!file_exists($file)) {
056 return array();
057 }
058
059 $file = fopen($file, 'r');
060 fseek($file, 0, SEEK_END);
061
062 $result = array();
063 while (count($result) < $limit && $line = $this->readLineFromFile($file)) {
064 list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line);
065
066 $csvTime = (int) $csvTime;
067
068 if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) {
069 continue;
070 }
071
072 if (!empty($start) && $csvTime < $start) {
073 continue;
074 }
075
076 if (!empty($end) && $csvTime > $end) {
077 continue;
078 }
079
080 $result[$csvToken] = array(
081 'token' => $csvToken,
082 'ip' => $csvIp,
083 'method' => $csvMethod,
084 'url' => $csvUrl,
085 'time' => $csvTime,
086 'parent' => $csvParent,
087 );
088 }
089
090 fclose($file);
091
092 return array_values($result);
093 }
094
095 /**
096 * {@inheritdoc}
097 */
098 public function purge()
099 {
100 $flags = \FilesystemIterator::SKIP_DOTS;
101 $iterator = new \RecursiveDirectoryIterator($this->folder, $flags);
102 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
103
104 foreach ($iterator as $file) {
105 if (is_file($file)) {
106 unlink($file);
107 } else {
108 rmdir($file);
109 }
110 }
111 }
112
113 /**
114 * {@inheritdoc}
115 */
116 public function read($token)
117 {
118 if (!$token || !file_exists($file = $this->getFilename($token))) {
119 return;
120 }
121
122 return $this->createProfileFromData($token, unserialize(file_get_contents($file)));
123 }
124
125 /**
126 * {@inheritdoc}
127 */
128 public function write(Profile $profile)
129 {
130 $file = $this->getFilename($profile->getToken());
131
132 $profileIndexed = is_file($file);
133 if (!$profileIndexed) {
134 // Create directory
135 $dir = dirname($file);
136 if (!is_dir($dir)) {
137 mkdir($dir, 0777, true);
138 }
139 }
140
141 // Store profile
142 $data = array(
143 'token' => $profile->getToken(),
144 'parent' => $profile->getParentToken(),
145 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
146 'data' => $profile->getCollectors(),
147 'ip' => $profile->getIp(),
148 'method' => $profile->getMethod(),
149 'url' => $profile->getUrl(),
150 'time' => $profile->getTime(),
151 );
152
153 if (false === file_put_contents($file, serialize($data))) {
154 return false;
155 }
156
157 if (!$profileIndexed) {
158 // Add to index
159 if (false === $file = fopen($this->getIndexFilename(), 'a')) {
160 return false;
161 }
162
163 fputcsv($file, array(
164 $profile->getToken(),
165 $profile->getIp(),
166 $profile->getMethod(),
167 $profile->getUrl(),
168 $profile->getTime(),
169 $profile->getParentToken(),
170 ));
171 fclose($file);
172 }
173
174 return true;
175 }
176
177 /**
178 * Gets filename to store data, associated to the token.
179 *
180 * @param string $token
181 *
182 * @return string The profile filename
183 */
184 protected function getFilename($token)
185 {
186 // Uses 4 last characters, because first are mostly the same.
187 $folderA = substr($token, -2, 2);
188 $folderB = substr($token, -4, 2);
189
190 return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token;
191 }
192
193 /**
194 * Gets the index filename.
195 *
196 * @return string The index filename
197 */
198 protected function getIndexFilename()
199 {
200 return $this->folder.'/index.csv';
201 }
202
203 /**
204 * Reads a line in the file, backward.
205 *
206 * This function automatically skips the empty lines and do not include the line return in result value.
207 *
208 * @param resource $file The file resource, with the pointer placed at the end of the line to read
209 *
210 * @return mixed A string representing the line or null if beginning of file is reached
211 */
212 protected function readLineFromFile($file)
213 {
214 $line = '';
215 $position = ftell($file);
216
217 if (0 === $position) {
218 return;
219 }
220
221 while (true) {
222 $chunkSize = min($position, 1024);
223 $position -= $chunkSize;
224 fseek($file, $position);
225
226 if (0 === $chunkSize) {
227 // bof reached
228 break;
229 }
230
231 $buffer = fread($file, $chunkSize);
232
233 if (false === ($upTo = strrpos($buffer, "\n"))) {
234 $line = $buffer.$line;
235 continue;
236 }
237
238 $position += $upTo;
239 $line = substr($buffer, $upTo + 1).$line;
240 fseek($file, max(0, $position), SEEK_SET);
241
242 if ('' !== $line) {
243 break;
244 }
245 }
246
247 return '' === $line ? null : $line;
248 }
249
250 protected function createProfileFromData($token, $data, $parent = null)
251 {
252 $profile = new Profile($token);
253 $profile->setIp($data['ip']);
254 $profile->setMethod($data['method']);
255 $profile->setUrl($data['url']);
256 $profile->setTime($data['time']);
257 $profile->setCollectors($data['data']);
258
259 if (!$parent && $data['parent']) {
260 $parent = $this->read($data['parent']);
261 }
262
263 if ($parent) {
264 $profile->setParent($parent);
265 }
266
267 foreach ($data['children'] as $token) {
268 if (!$token || !file_exists($file = $this->getFilename($token))) {
269 continue;
270 }
271
272 $profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile));
273 }
274
275 return $profile;
276 }
277 }
278