質問編集履歴

1

Feed.phpを追加しました。

2021/07/23 10:53

投稿

kumagaya31
kumagaya31

スコア0

test CHANGED
File without changes
test CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
 
26
26
 
27
- ### 該当のソースコード
27
+ ### Sample.php
28
28
 
29
29
 
30
30
 
@@ -131,3 +131,551 @@
131
131
 
132
132
 
133
133
  ```
134
+
135
+
136
+
137
+ ### Feed.php
138
+
139
+ ```PHP
140
+
141
+ <?php
142
+
143
+
144
+
145
+ /**
146
+
147
+ * RSS for PHP - small and easy-to-use library for consuming an RSS Feed
148
+
149
+ *
150
+
151
+ * @copyright Copyright (c) 2008 David Grudl
152
+
153
+ * @license New BSD License
154
+
155
+ * @version 1.5
156
+
157
+ */
158
+
159
+ class Feed
160
+
161
+ {
162
+
163
+ /** @var int */
164
+
165
+ public static $cacheExpire = '1 day';
166
+
167
+
168
+
169
+ /** @var string */
170
+
171
+ public static $cacheDir;
172
+
173
+
174
+
175
+ /** @var string */
176
+
177
+ public static $userAgent = 'FeedFetcher-Google';
178
+
179
+
180
+
181
+ /** @var SimpleXMLElement */
182
+
183
+ protected $xml;
184
+
185
+
186
+
187
+
188
+
189
+ /**
190
+
191
+ * Loads RSS or Atom feed.
192
+
193
+ * @param string
194
+
195
+ * @param string
196
+
197
+ * @param string
198
+
199
+ * @return Feed
200
+
201
+ * @throws FeedException
202
+
203
+ */
204
+
205
+ public static function load($url, $user = null, $pass = null)
206
+
207
+ {
208
+
209
+ $xml = self::loadXml($url, $user, $pass);
210
+
211
+ if ($xml->channel) {
212
+
213
+ return self::fromRss($xml);
214
+
215
+ } else {
216
+
217
+ return self::fromAtom($xml);
218
+
219
+ }
220
+
221
+ }
222
+
223
+
224
+
225
+
226
+
227
+ /**
228
+
229
+ * Loads RSS feed.
230
+
231
+ * @param string RSS feed URL
232
+
233
+ * @param string optional user name
234
+
235
+ * @param string optional password
236
+
237
+ * @return Feed
238
+
239
+ * @throws FeedException
240
+
241
+ */
242
+
243
+ public static function loadRss($url, $user = null, $pass = null)
244
+
245
+ {
246
+
247
+ return self::fromRss(self::loadXml($url, $user, $pass));
248
+
249
+ }
250
+
251
+
252
+
253
+
254
+
255
+ /**
256
+
257
+ * Loads Atom feed.
258
+
259
+ * @param string Atom feed URL
260
+
261
+ * @param string optional user name
262
+
263
+ * @param string optional password
264
+
265
+ * @return Feed
266
+
267
+ * @throws FeedException
268
+
269
+ */
270
+
271
+ public static function loadAtom($url, $user = null, $pass = null)
272
+
273
+ {
274
+
275
+ return self::fromAtom(self::loadXml($url, $user, $pass));
276
+
277
+ }
278
+
279
+
280
+
281
+
282
+
283
+ private static function fromRss(SimpleXMLElement $xml)
284
+
285
+ {
286
+
287
+ if (!$xml->channel) {
288
+
289
+ throw new FeedException('Invalid feed.');
290
+
291
+ }
292
+
293
+
294
+
295
+ self::adjustNamespaces($xml);
296
+
297
+
298
+
299
+ foreach ($xml->channel->item as $item) {
300
+
301
+ // converts namespaces to dotted tags
302
+
303
+ self::adjustNamespaces($item);
304
+
305
+
306
+
307
+ // generate 'url' & 'timestamp' tags
308
+
309
+ $item->url = (string) $item->link;
310
+
311
+ if (isset($item->{'dc:date'})) {
312
+
313
+ $item->timestamp = strtotime($item->{'dc:date'});
314
+
315
+ } elseif (isset($item->pubDate)) {
316
+
317
+ $item->timestamp = strtotime($item->pubDate);
318
+
319
+ }
320
+
321
+ }
322
+
323
+ $feed = new self;
324
+
325
+ $feed->xml = $xml->channel;
326
+
327
+ return $feed;
328
+
329
+ }
330
+
331
+
332
+
333
+
334
+
335
+ private static function fromAtom(SimpleXMLElement $xml)
336
+
337
+ {
338
+
339
+ if (!in_array('http://www.w3.org/2005/Atom', $xml->getDocNamespaces(), true)
340
+
341
+ && !in_array('http://purl.org/atom/ns#', $xml->getDocNamespaces(), true)
342
+
343
+ ) {
344
+
345
+ throw new FeedException('Invalid feed.');
346
+
347
+ }
348
+
349
+
350
+
351
+ // generate 'url' & 'timestamp' tags
352
+
353
+ foreach ($xml->entry as $entry) {
354
+
355
+ $entry->url = (string) $entry->link['href'];
356
+
357
+ $entry->timestamp = strtotime($entry->updated);
358
+
359
+ }
360
+
361
+ $feed = new self;
362
+
363
+ $feed->xml = $xml;
364
+
365
+ return $feed;
366
+
367
+ }
368
+
369
+
370
+
371
+
372
+
373
+ /**
374
+
375
+ * Returns property value. Do not call directly.
376
+
377
+ * @param string tag name
378
+
379
+ * @return SimpleXMLElement
380
+
381
+ */
382
+
383
+ public function __get($name)
384
+
385
+ {
386
+
387
+ return $this->xml->{$name};
388
+
389
+ }
390
+
391
+
392
+
393
+
394
+
395
+ /**
396
+
397
+ * Sets value of a property. Do not call directly.
398
+
399
+ * @param string property name
400
+
401
+ * @param mixed property value
402
+
403
+ * @return void
404
+
405
+ */
406
+
407
+ public function __set($name, $value)
408
+
409
+ {
410
+
411
+ throw new Exception("Cannot assign to a read-only property '$name'.");
412
+
413
+ }
414
+
415
+
416
+
417
+
418
+
419
+ /**
420
+
421
+ * Converts a SimpleXMLElement into an array.
422
+
423
+ * @param SimpleXMLElement
424
+
425
+ * @return array
426
+
427
+ */
428
+
429
+ public function toArray(SimpleXMLElement $xml = null)
430
+
431
+ {
432
+
433
+ if ($xml === null) {
434
+
435
+ $xml = $this->xml;
436
+
437
+ }
438
+
439
+
440
+
441
+ if (!$xml->children()) {
442
+
443
+ return (string) $xml;
444
+
445
+ }
446
+
447
+
448
+
449
+ $arr = [];
450
+
451
+ foreach ($xml->children() as $tag => $child) {
452
+
453
+ if (count($xml->$tag) === 1) {
454
+
455
+ $arr[$tag] = $this->toArray($child);
456
+
457
+ } else {
458
+
459
+ $arr[$tag][] = $this->toArray($child);
460
+
461
+ }
462
+
463
+ }
464
+
465
+
466
+
467
+ return $arr;
468
+
469
+ }
470
+
471
+
472
+
473
+
474
+
475
+ /**
476
+
477
+ * Load XML from cache or HTTP.
478
+
479
+ * @param string
480
+
481
+ * @param string
482
+
483
+ * @param string
484
+
485
+ * @return SimpleXMLElement
486
+
487
+ * @throws FeedException
488
+
489
+ */
490
+
491
+ private static function loadXml($url, $user, $pass)
492
+
493
+ {
494
+
495
+ $e = self::$cacheExpire;
496
+
497
+ $cacheFile = self::$cacheDir . '/feed.' . md5(serialize(func_get_args())) . '.xml';
498
+
499
+
500
+
501
+ if (self::$cacheDir
502
+
503
+ && (time() - @filemtime($cacheFile) <= (is_string($e) ? strtotime($e) - time() : $e))
504
+
505
+ && $data = @file_get_contents($cacheFile)
506
+
507
+ ) {
508
+
509
+ // ok
510
+
511
+ } elseif ($data = trim(self::httpRequest($url, $user, $pass))) {
512
+
513
+ if (self::$cacheDir) {
514
+
515
+ file_put_contents($cacheFile, $data);
516
+
517
+ }
518
+
519
+ } elseif (self::$cacheDir && $data = @file_get_contents($cacheFile)) {
520
+
521
+ // ok
522
+
523
+ } else {
524
+
525
+ throw new FeedException('Cannot load feed.');
526
+
527
+ }
528
+
529
+
530
+
531
+ return new SimpleXMLElement($data, LIBXML_NOWARNING | LIBXML_NOERROR | LIBXML_NOCDATA);
532
+
533
+ }
534
+
535
+
536
+
537
+
538
+
539
+ /**
540
+
541
+ * Process HTTP request.
542
+
543
+ * @param string
544
+
545
+ * @param string
546
+
547
+ * @param string
548
+
549
+ * @return string|false
550
+
551
+ * @throws FeedException
552
+
553
+ */
554
+
555
+ private static function httpRequest($url, $user, $pass)
556
+
557
+ {
558
+
559
+ if (extension_loaded('curl')) {
560
+
561
+ $curl = curl_init();
562
+
563
+ curl_setopt($curl, CURLOPT_URL, $url);
564
+
565
+ if ($user !== null || $pass !== null) {
566
+
567
+ curl_setopt($curl, CURLOPT_USERPWD, "$user:$pass");
568
+
569
+ }
570
+
571
+ curl_setopt($curl, CURLOPT_USERAGENT, self::$userAgent); // some feeds require a user agent
572
+
573
+ curl_setopt($curl, CURLOPT_HEADER, false);
574
+
575
+ curl_setopt($curl, CURLOPT_TIMEOUT, 20);
576
+
577
+ curl_setopt($curl, CURLOPT_ENCODING, '');
578
+
579
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // no echo, just return result
580
+
581
+ if (!ini_get('open_basedir')) {
582
+
583
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // sometime is useful :)
584
+
585
+ }
586
+
587
+ $result = curl_exec($curl);
588
+
589
+ return curl_errno($curl) === 0 && curl_getinfo($curl, CURLINFO_HTTP_CODE) === 200
590
+
591
+ ? $result
592
+
593
+ : false;
594
+
595
+
596
+
597
+ } else {
598
+
599
+ $context = null;
600
+
601
+ if ($user !== null && $pass !== null) {
602
+
603
+ $options = [
604
+
605
+ 'http' => [
606
+
607
+ 'method' => 'GET',
608
+
609
+ 'header' => 'Authorization: Basic ' . base64_encode($user . ':' . $pass) . "\r\n",
610
+
611
+ ],
612
+
613
+ ];
614
+
615
+ $context = stream_context_create($options);
616
+
617
+ }
618
+
619
+
620
+
621
+ return file_get_contents($url, false, $context);
622
+
623
+ }
624
+
625
+ }
626
+
627
+
628
+
629
+
630
+
631
+ /**
632
+
633
+ * Generates better accessible namespaced tags.
634
+
635
+ * @param SimpleXMLElement
636
+
637
+ * @return void
638
+
639
+ */
640
+
641
+ private static function adjustNamespaces($el)
642
+
643
+ {
644
+
645
+ foreach ($el->getNamespaces(true) as $prefix => $ns) {
646
+
647
+ $children = $el->children($ns);
648
+
649
+ foreach ($children as $tag => $content) {
650
+
651
+ $el->{$prefix . ':' . $tag} = $content;
652
+
653
+ }
654
+
655
+ }
656
+
657
+ }
658
+
659
+ }
660
+
661
+
662
+
663
+
664
+
665
+
666
+
667
+ /**
668
+
669
+ * An exception generated by Feed.
670
+
671
+ */
672
+
673
+ class FeedException extends Exception
674
+
675
+ {
676
+
677
+ }
678
+
679
+
680
+
681
+ ```