login  Naam:   Wachtwoord: 
Registreer je!
 Forum

OOP Rss lezer met vorige / volgende functie (Opgelost)

Offline GroundZero - 01/03/2016 10:56
Avatar van GroundZeroLid Beste,

ik ben OOP aan het leren, maar wil nu dus het volgende bereiken.

Ik heb een class geschreven welke prima werkt namelijk:

  1. <?php
  2. ini_set('display_errors', '1');
  3.  
  4. class feedReader {
  5. public $content = array('http://www.nu.nl/rss/Internet',
  6. 'http://www.nu.nl/rss/Lifehacking',
  7. 'http://www.nu.nl/rss/Plugged',
  8. 'http://www.nu.nl/rss/Games',
  9. 'http://www.nu.nl/rss/Film',
  10. 'http://www.nu.nl/rss/DVD',
  11. 'http://www.nu.nl/rss/Wetenschap');
  12. public $start = 0;
  13. public $rss;
  14. public $items = array();
  15.  
  16. function __construct () {
  17. $file = file_get_contents($this->content[$this->start]);
  18. $this->rss = new SimpleXMLElement($file);
  19. }
  20.  
  21. function previous () {
  22. if($this->start == 0) {
  23. $this->start = count($this->content);
  24. } else {
  25. $this->start--;
  26. }
  27.  
  28. $file = file_get_contents($this->content[$this->start]);
  29. $this->rss = new SimpleXMLElement($file);
  30. }
  31.  
  32. function nextOne () {
  33. if($this->start == count($this->content)) {
  34. $this->start = 0;
  35. } else {
  36. $this->start++;
  37. }
  38.  
  39. $file = file_get_contents($this->content[$this->start]);
  40. $this->rss = new SimpleXMLElement($file);
  41. }
  42.  
  43. function display () {
  44. foreach($this->rss->channel->item as $item)
  45. {
  46. echo $item->title;
  47. }
  48. }
  49. }
  50. ?>


Echter nu het probleem. Ik heb in mijn HTML een aantal div's. Eén daarvoor is een "vorige" knop, één is de "volgende" knop en de laatste is waar de content in moet komen.

Hoe kan ik er nu voor zorgen, dat aan de hand van deze class, als iemand op vorige / volgende klikt dat de content in de div veranderd? wat is hiervoor de correcte manier?

Ik kan wel jQuery er doorheen gaan mensen, maar ik weet niet of dit de correcte manier is om zo iets te doen (gebrek aan ervaring).

Hopelijk kan een van jullie mij vertellen hoe dit aan te pakken 

Dus bijvoorbeeld:

  1. function nextOne () {
  2. if($this->start == count($this->content)) {
  3. $this->start = 0;
  4. } else {
  5. $this->start++;
  6. }
  7.  
  8. $file = file_get_contents($this->content[$this->start]);
  9. $this->rss = new SimpleXMLElement($file);
  10.  
  11. ?>
  12.  
  13. <script>
  14. $.ajax({});
  15. </script>
  16.  
  17. <?php
  18. }


bijvoorbeeld 

7 antwoorden

Gesponsorde links
Offline Thomas - 01/03/2016 15:11
Avatar van Thomas Moderator Hoe je iets weergeeft staat in principe los van hoe je iets ophaalt.

In dat opzicht zijn de methoden "previous" en "nextOne" nogal curieus. Daarnaast doen ze alle (alsmede je constructor) ongeveer hetzelfde. Een goed ontwerpprincipe is Don't Repeat Yourself. Ook is de naamgeving niet helemaal consistent, maar dat doet er niet toe want ik zou deze methoden niet gebruiken.

Je moet je ook afvragen wat er gebeurt als er genavigeerd wordt van pagina A naar pagina B. Je objecten zijn niet persistent, dat wil zeggen, ze blijven niet bestaan. Al het geheugen wat een script gebruikt, en hiertoe behoren ook variabelen, objecten en de hele rimram worden normaal gesproken vrijgegeven wanneer het script klaar is met zijn uitvoer. Er is geen historie van een "huidig" of "vorig" element tenzij je dit op een of andere manier propageert van pagina A naar pagina B (via de URL, een sessie, een cookie, whatever).

Ook de public property content is nogal raar, deze bevat een hardcoded lijst met feeds.

Ik denk dat deze class vanuit een OOP-point-of-view niet echt de goede insteek heeft, onder andere om de volgende redenen:
* normaal verzorgt één class één taak, in dit geval zou je een class kunnen schrijven die een feed ophaalt en alvast een soort van voorbewerking doet voor makkelijk gebruik zodat deze class een zekere meerwaarde heeft; op dit moment is het niet echt meer dan een wrapper voor file_get_contents / SimpleXML aanroepen, dat rechtvaardigt de inzet van een class nog niet echt.

* een class moet herbruikbaar zijn; als je dan toch een class schrijft die toegespitst is op het ophalen van een feed, dan zou je dit bijvoorbeeld kunnen regelen door je constructor te voorzien van een parameter waarmee je de feedlocatie kunt opgeven (in plaats van die hardcoded lijst).

De logica voor het weergeven van en navigeren door verschillende feeds hoort niet echt in deze class thuis (als deze enkel tot doel het ophalen ervan zou hebben).

Je zou deze class nog uit kunnen breiden met caching (en deze caching zou je weer onder kunnen brengen in een aparte class omdat dit een andere/specifiekere taak is).

Nu haal je de feed elke keer opnieuw op. Wat gebeurt er als meerdere mensen vrolijk door jouw applicatie heenklikken? Als het een beetje druk wordt dan wordt nu.nl gebombardeerd met requests...
Offline GroundZero - 01/03/2016 15:24
Avatar van GroundZero Lid Het ging mij er meer even om hoe ik in de feeds tussen de volgende in de array en de vorige kan switchen en dit kan weergeven. een caching zou er uiteraard in zitten en betreft de array IN de class zelf, ook dit was voor de handigheid even zo gedaan, normaal geef ik dit als attribuut mee inderdaad.

Echter wel allemaal goede punten, maar het gaat mij puur om hoe kan ik het 't beste doen dat je op een volgende / vorige knop kan klikken en dat de volgende of vorige uit de array gekozen word en weergegeven word ;)

Echter wel een top antwoord van je met veel goede punten! maar het punt is echt:

Ik kan een volgende en vorige kiezen, dit werkt... maar hoe nu weergeven. Gewoon een PHP afsluit tag doen en daar jQuery neer gooien? of wat zou een correcte manier zijn om zoiets te doen?

Ik heb vaker dit soort dingen gemaakt maar niet in OOP. Dan doe ik het met jQuery en cache ik het in MYSQLi of anders in een tekst bestand zodat het inderdaad niet elke keer opnieuw opgehaald hoeft te worden.
Offline Rens - 01/03/2016 15:49
Avatar van Rens Gouden medaille

Crew algemeen
Als het er om gaat dat het live veranderd word zul je inderdaad iets als jQuery / Ajax moeten gaan gebruiken.
Als er een pagina refresh bij mag komen kun je gebruik maken van een 'Pagina Navigatie'.

Of wel:
Vorige --> pagina.php?link=1
Huidige
Volgende --> pagina.php?link=3

En dan in je navigatie laten bekijken wat de startpositie is.

Zonder 1 van beide (page nav of Ajax / jQuery) gaat dit je niet lukken denk ik...
Beide manieren zijn correct, de ene misschien wat simpeler (page nav) maar de andere weer wat 'blitser' (ajax / jQuery).
Offline Thomas - 01/03/2016 17:58
Avatar van Thomas Moderator Oh, het betreft dus in eerste instantie enkel een navigatie-issue.

Zoals Rens al aangeeft, je zult hoe dan ook de feeds op een of andere manier moeten identificeren. Geef ze een (auto-increment) nummer of refereer aan een statische lijst. Dit id geef je bijvoorbeeld door via de URL, lijkt mij het handigste.

Hoe je deze informatie vervolgens binnenharkt en/of afdrukt: wat jij leuk vindt. Het bekijken van een feed hoeft wat mij betreft niet via een of andere achtergrondroutine (ajax/jQuery) te lopen tenzij je een soort van interactief controlepaneel hebt ofzo, waarop (veel) meer informatie wordt getoond. Als je enkel, en "exclusief", de feed bekijkt op een aparte pagina zou ik dit niet via ajax/jQuery doen.

Daarbij ook de observatie dat hetgene je doet op de afzonderlijke pagina, en de informatie die je binnentrekt via ajax/jQuery haast op eenzelfde wijze geschiedt: je haalt de informatie op van één feed middels een identifier. En of je dit nu transporteert als JSON of als een plak HTML, dat is eigenlijk om het even. Ik zie dan ook niet echt een groot technisch verschil tussen deze twee. Welke handiger is is meer persoonlijke voorkeur dan een echte grote ontwerpbeslissing. De uitwerking (het hoe) is eigenlijk triviaal ten opzichte van de aanpak (het wat). Het missende puzzelstukje is wellicht een manier om een feed uniek te identificeren.

Als ik nieuws uit een bepaalde rubriek bekijk ben ik trouwens meestal geinteresseerd in een specifieke rubriek, het komt zelden tot nooit voor dat ik door alle rubrieken heenblader. Misschien moet je dit meenemen in je overweging om in plaats van een vorige/volgende aanpak te gaan voor een variant waarbij je direct een rubriek kunt selecteren? Of beide.
Offline GroundZero - 03/03/2016 17:41 (laatste wijziging 03/03/2016 19:36)
Avatar van GroundZero Lid Even voor de duidelijkheid de opdracht hier wat ik moet leren:

Bouw een nieuws applicatie waarmee het laatste nieuws wordt gepresenteerd,
gebruikmakend van de RSS-feeds van Nu.nl,
waarbij de gebruiker zelf van ‘kanaal’ kan wisselen


Waar ik nu dus niet uit kom is hoe ik naar de volgende feed kan gaan (url) en deze kan weergeven... dit is een niet werkend voorbeeld maar bijvoorbeeld het volgende voorbeeld zoals onderstaand.

Overigens kan er veel beter en mooier dat weet ik, maar het gaat mij er nu enkel om hoe ik naar volgende en vorige kan gaan en de resultaten met jQuery in de desbetreffende div kan weergeven that's all 

Feed class
  1. <script src="../js/jquery-1.12.1.min.js"></script>
  2.  
  3. <?php
  4. class feedReader {
  5. public $content = array('http://www.nu.nl/rss/Internet',
  6. 'http://www.nu.nl/rss/Lifehacking',
  7. 'http://www.nu.nl/rss/Plugged',
  8. 'http://www.nu.nl/rss/Games',
  9. 'http://www.nu.nl/rss/Film',
  10. 'http://www.nu.nl/rss/DVD',
  11. 'http://www.nu.nl/rss/Wetenschap');
  12. public $start = 0;
  13. public $rss;
  14. public $items = array();
  15.  
  16.  
  17. function __construct () {
  18. $file = file_get_contents( $this->content[0] );
  19. $this->rss = new SimpleXMLElement( $file );
  20. }
  21.  
  22. function previous () {
  23. if($this->content == 0) {
  24. $this->content = count($this->content);
  25. } else {
  26. $this->content--;
  27. }
  28. }
  29.  
  30. function nextOne () {
  31. if($this->content == count($this->content)) {
  32. $this->content = 0;
  33. } else {
  34. $this->content++;
  35. }
  36. }
  37.  
  38. function display () {
  39.  
  40. $view = [];
  41.  
  42. foreach($this->rss->channel->item as $item)
  43. {
  44. $view[] = $item->title;
  45. }
  46.  
  47. return $view;
  48.  
  49. }
  50.  
  51. }
  52. ?>


de PHP (voorkant)

  1. <?php
  2. ini_set('display_errors', '1');
  3.  
  4. /**
  5. * include manditory files
  6. **/
  7. require_once('includes/config.php');
  8. require_once('includes/feed_class.php');
  9.  
  10. $feed = new feedReader();
  11. $out = $feed->display();
  12. ?>
  13.  
  14. <!doctype html>
  15. <html>
  16. <head>
  17.  
  18. <meta charset="utf-8">
  19.  
  20. <title>Naamloos document</title>
  21.  
  22. <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css" />
  23.  
  24. <link rel="stylesheet" href="css/bootstrap.min.css" />
  25. <link rel="stylesheet" href="css/font-awesome.min.css" />
  26. <link rel="stylesheet" href="css/style.css" />
  27.  
  28. </head>
  29. <body>
  30.  
  31. <div class="container">
  32. <div class="row">
  33. <div class="col-md-4">
  34.  
  35. <!-- start feed widget -->
  36.  
  37. <div class="fw_header">
  38. <div class="fw_previous">
  39. <a href="#" title="Show previous category" data-action="loadPrevious">
  40. <i class="fa fa-backward"></i>
  41. </a>
  42. </div>
  43. <div class="fw_current">
  44.  
  45. </div>
  46. <div class="fw_next">
  47. <a href="#" title="Show next category" data-action="loadNext">
  48. <i class="fa fa-forward"></i>
  49. </a>
  50. </div>
  51. </div>
  52. <div class="fw_content">
  53.  
  54. </div>
  55.  
  56. <!-- end feed widget -->
  57.  
  58. </div>
  59. <div class="col-md-8">
  60. <article>
  61.  
  62. </article>
  63. </div>
  64. </div>
  65. </div>
  66.  
  67. <script src="js/jquery-1.12.1.min.js"></script>
  68. <script src="js/bootstrap.min.js"></script>
  69. <script>
  70. $(document).ready(function() {
  71. var outcome = <?php echo json_encode($out) ?>;
  72. var i;
  73.  
  74. for(i = 0; i < outcome.length; i++) {
  75. $('.fw_content').append( '<div class="rss_item_title">' + outcome[i][0] + '</div>' );
  76. }
  77. });
  78.  
  79. $('[data-action="loadNext"]').click(function(event){
  80. <?php
  81. $feed->nextOne();
  82. $out = $feed->display();
  83. ?>
  84.  
  85. console.log( '<?php echo $out ?>' );
  86. });
  87. </script>
  88.  
  89. </body>
  90. </html>
Offline Thomas - 04/03/2016 15:54 (laatste wijziging 04/03/2016 16:15)
Avatar van Thomas Moderator Ik denk dat de punten van Rens en mij niet helemaal zijn aangekomen. Laat ik het nogmaals proberen uit te leggen.

Je moet het zo zien: om te weten waar je naartoe gaat, moet je weten waar je bent. Op dit moment wordt dat niet bijgehouden. Vorige feed? Volgende feed? Ten opzichte van wat? Dat is het punt een beetje nog steeds: de feeds worden niet (via de buitenwereld) geïdentificeerd als A of B. Dan weet je dus ook niet dat B volgt op A.

Ook is het wellicht handig om een soort van verdeel-en-heers strategie te volgen. Het fysiek ophalen van een specifieke feed (of een gecached exemplaar hiervan ) heeft weinig (niets?) van doen hoe je deze weergeeft of hoe je deze combineert in een navigatie. Probeer deze taken dan ook niet te combineren maar splits ze (verdeel) en los ze vervolgens stuk voor stuk op (heers).

Hieronder een voorbeeld van een aanpak van hoe de navigatie zou kunnen verlopen. In dit geval met pagina-refreshes, maar op eenzelfde manier kun je iets met jQuery/AJAX bouwen. De crux is dat je een statische lijst van feeds hebt waar je aan kunt refereren die "globaal" bekend is, en dat je op een of andere manier onthoudt bij welke (huidge) feed je zit. Alleen dan kun je op een zinnige manier spreken over "vorige" en "volgende".

De class of functionaliteit die een feed ophaalt (op wat voor manier dan ook) heeft in principe al deze informatie niet nodig - deze moet enkel een feed op kunnen halen en weer kunnen geven (dit laatste kun je trouwens ook weer in een aparte class/stuk functionaliteit onderbrengen als je wilt).

Met het volgende voorbeeld is eigenlijk de helft van het werk al gedaan (de navigatie). De rest mag je voor je eigen rekening nemen.

  1. <?php
  2. header('Content-Type: text/html; charset=UTF-8'); // alles UTF-8
  3.  
  4. // Shorthand voor output escaping.
  5. function escape($in) {
  6. return htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
  7. }
  8.  
  9. // Lijst met feeds
  10. // Het kan ook handig zijn om hier wat "data verrijking" te doen.
  11. // Voorzie deze feeds bijvoorbeeld van een titel of korte omschrijving.
  12. // Merk op dat het id eigenlijk een willekeurig nummer kan zijn, zolang deze uniek is.
  13. // Omdat het op voorhand niet vaststaat welke elementen buren van elkaar zijn is het handig om
  14. // een "dubbel gelinkte lijst" te bouwen. Als je deze lijst normaal genereert vanuit een database
  15. // met feeds dan kun je eenvoudig tijdens het genereren deze informatie on-the-fly uitrekenen en toevoegen.
  16. $feeds = array(
  17. 1 => array(
  18. 'title' => 'Internet',
  19. 'source' => 'http://www.nu.nl/rss/Internet',
  20. 'previous' => false, // de eerste feed heeft geen voorganger
  21. 'next' => 2,
  22. ),
  23. 2 => array(
  24. 'title' => 'Lifehacking',
  25. 'source' => 'http://www.nu.nl/rss/Lifehacking',
  26. 'previous' => 1,
  27. 'next' => 3,
  28. ),
  29. 3 => array(
  30. 'title' => 'Plugged',
  31. 'source' => 'http://www.nu.nl/rss/Plugged',
  32. 'previous' => 2,
  33. 'next' => 4,
  34. ),
  35. 4 => array(
  36. 'title' => 'Games',
  37. 'source' => 'http://www.nu.nl/rss/Games',
  38. 'previous' => 3,
  39. 'next' => 12345,
  40. ),
  41. 12345 => array(
  42. 'title' => 'Film',
  43. 'source' => 'http://www.nu.nl/rss/Film',
  44. 'previous' => 4,
  45. 'next' => 6,
  46. ),
  47. 6 => array(
  48. 'title' => 'DVD',
  49. 'source' => 'http://www.nu.nl/rss/DVD',
  50. 'previous' => 12345,
  51. 'next' => 7,
  52. ),
  53. 7 => array(
  54. 'title' => 'Wetenschap',
  55. 'source' => 'http://www.nu.nl/rss/Wetenschap',
  56. 'previous' => 6,
  57. 'next' => false, // de laatste feed heeft geen opvolger
  58. ),
  59. // etc
  60. );
  61.  
  62. // Wat is het huidige item?
  63. if (isset($_GET['id']) && array_key_exists($_GET['id'], $feeds)) {
  64. $currentId = $_GET['id'];
  65. } else {
  66. $currentId = false;
  67. }
  68. ?>
  69. <!DOCTYPE html>
  70. <html>
  71. <head>
  72. <meta charset="UTF-8">
  73. <title>Er Es Es fiets</title>
  74. <style type="text/css">
  75. body { font-family: sans-serif; font-size: 10pt; }
  76. div.navigatie { }
  77. div.navigatie div.cell { float: left; width: 100px; height: 25px; line-height: 25px; }
  78. div.clear { clear: both; }
  79. </style>
  80. </head>
  81.  
  82. <body>
  83. <div class="navigatie">
  84. <!-- previous -->
  85. <div class="cell"><?php
  86. if ($currentId !== false && $feeds[$currentId]['previous'] !== false) {
  87. ?><a href="?id=<?php echo escape($feeds[$currentId]['previous']) ?>">vorige</a><?php
  88. }
  89. ?></div>
  90. <!-- current -->
  91. <div class="cell">
  92. <select onchange="window.location = '?id='+this.value;">
  93. <option value="">- selecteer -</option><?php
  94. foreach ($feeds as $id => $data) {
  95. $selected = ($id == $currentId ? ' selected="selected"' : '');
  96. ?><option value="<?php echo escape($id) ?>"<?php echo $selected ?>><?php echo escape($data['title']) ?></option><?php
  97. }
  98. ?></select>
  99. </div>
  100. <!-- next -->
  101. <div class="cell" style="text-align: right;"><?php
  102. if ($currentId !== false && $feeds[$currentId]['next'] !== false) {
  103. ?><a href="?id=<?php echo escape($feeds[$currentId]['next']) ?>">volgende</a><?php
  104. }
  105. ?></div>
  106. <div class="clear"><!-- clear --></div>
  107. </div><?php
  108. if ($currentId === false) {
  109. ?><p>Selecteer een feed.</p><?php
  110. } else {
  111. // En hier kun je dan eventueel de feed ophalen met $feed['source'].
  112. $feed = $feeds[$currentId];
  113. ?>@todo: ophalen feed <strong><?php echo escape($feed['title']) ?></strong> met bron <?php echo escape($feed['source']) ?>.</p><?php
  114. }
  115. ?></body>
  116. </html>
Bedankt door: GroundZero
Offline GroundZero - 25/03/2016 12:35
Avatar van GroundZero Lid Goed antwoord, veel informatie dankjewel! in mijn huidige ontwerp zou hij inderdaad niet onthouden waar je momenteel bent en in jouw voorbeeld code wel.

Ik ga dit weekend eens proberen om jouw code verder uit te werken en het goed werkend te krijgen voor mijn doeleinde.

Dankjewel!
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.407s