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