Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]Call to a member function on a non-object
Forum PHP.pl > Forum > Przedszkole
onlyX
Witam!

Przerabiam kod strukturalny na klasę i napotkałem błąd.
Najpierw kod:
  1. <?php
  2.  
  3. require_once 'bbcode/stringparser_bbcode.class.php';
  4.  
  5.  
  6. //kontener 
  7. class BBCode{
  8.  
  9. var $bbcode;
  10.  
  11. //konstruktor
  12. function BBCode() {
  13. $bbcode = new StringParser_BBCode ();
  14.  
  15. $bbcode->setParagraphHandlingParameters ("\n\n", "<p>", "</p>");
  16.  
  17. //PHP
  18. $bbcode->addCode ('php', 'callback_replace', 'callbackPHP', array ('start_tag' => '<code>', 'end_tag' => '</code>'),
  19. 'code', array ('block', 'inline'), array ('code'));
  20. }
  21.  
  22. //callbacki
  23. //PHP
  24. function callbackPHP($action, $attributes, $content, $params, &$node_object) {
  25. return codeHighlight($content, 'php');
  26. }
  27.  
  28. //funkcja kolorujaca kod za pomoca Geshi'
  29. function codeHighlight($str, $lang) {
  30. //tymczasowo
  31. return 'jezyk: '.$lang.' kod: '.$str;
  32. }
  33. }
  34.  
  35.  
  36. //----- MAIN -------
  37. if (!empty($_POST['text'])) {
  38.  
  39. $bbcode = new BBCode();
  40. echo $bbcode->bbcode->parse ($_POST['text']);
  41. }
  42.  
  43. ?>


Po wysłaniu formularza otrzymałem błąd:
  1. Fatal error: Call to a member function parse() on a non-object in E:\WORKS\_usr\highlight\withbbcode2.php on line 39

W przed przepisaniem do klasy nie miałem tego problemu, wszystko działało poprawnie. Gdzie zrobiłem błąd?
sniezny_wilk
$bbcode->bbcode - jest zmienną, a nie obiektem stąd nie możesz wywołać funkcji parse.
nevt
Po pierwsze - prosze dodać odpowiedni tag do tematu - zgodnie z zasadami publikacji w przedszkolu - inaczej zamknę lub usunę temat.

a co do problemu.
kod który przerabiasz pochodzi z PHP4 a prawdopodobnie odpalasz go na serwerze PHP5
a różnica jest taka, że w 4 konstruktor klasy miał taką samą nazwę jak klasa, a w 5 to po prostu __construct()

więc:
  1. <?php
  2. // zamień
  3. function BBCode() {
  4.  
  5. // na
  6. public function __construct() {
  7. ?>

i będzie ok.
dr_bonzo
  1. <?php
  2. private $bbcode;
  3. function BBCode() {
  4. $bbcode = new StringParser_BBCode (); // tutaj uzywaz zmiennej lokalnej, zamiast $this->bbcode
  5. ?>

przez co potem

$bbcode->bbcode->parse() nie zadziala, bo ->bbcode jest nullem
onlyX
Już rozumiem. Dzięki!

Co ciekawe działa z oboma konstruktorami smile.gif a mam PHP 5
marcio
Cytat
Co ciekawe działa z oboma konstruktorami smile.gif a mam PHP 5

Dziala chyba dlatego ze w php5 mozna uruchamiac kody z php4 smile.gif
onlyX
Mniejsza o to.
Problemów ciąg dalszy: Funkcja addCode() powinna wywołać callbackPHP(), teraz nie chce. Jak się do niej odwołać. Przed przepisaniem do klasy działała.
  1. <?php
  2. //kontener 
  3. class BBCode{
  4.  
  5. var $bbcode;
  6.  
  7. //konstruktor
  8. public function __construct() {
  9. $this->bbcode = new StringParser_BBCode ();
  10.  
  11. $this->bbcode->setParagraphHandlingParameters ("\n\n", "<p>", "</p>");
  12.  
  13. //dodaj tag - funkcja powinna wywlywac funkcje callbackPHP
  14. $this->bbcode->addCode ('php', 'callback_replace', 'callbackPHP', array ('start_tag' => '<code>', 'end_tag' => '</code>'),
  15. 'code', array ('block', 'inline'), array ());
  16. }
  17.  
  18. //callbacki
  19. //PHP
  20. public function callbackPHP($action, $attributes, $content, $params, &$node_object) {
  21. echo '#DEBUG: wywolano callback'; //brak reakcji
  22. return codeHighlight($content, 'php');
  23. }
  24. }
  25. ?>
mike
A skąd mamy wiedzieć dlaczego addCode() nie wywołuje callbackPHP() skoro nie znamy jej implementacji?
Pokaż kod to pogadamy.
onlyX
Źle się wyraziłem. Funkcja addCode() dodaje BBkod, przy użyciu którego powinna się wywołać funkcja callbackPHP().

Chyba nie muszę podawać implementacji addCode. Myślałem, że wystarczy informacja, że kiedy wywoływałem je w taki sposób, przed przepisaniem do klasy, to callbackPHP się wykonywał. Teraz nie chce, więc podejrzewam, że to wina złego odwołania się do niej, źle podany parametr w addCode, czy coś podobnego.

Macie jakieś pomysły?
sniezny_wilk
Skoro mike poprosił to znaczy, że jest to potrzebne. Prawdopodobnie teraz masz ją (to funkcję) w klasie do której źle się odwołujesz.
onlyX
Skoro prosicie smile.gif
  1. <?php
  2. function addCode ($name, $callback_type, $callback_func, $callback_params, $content_type, $allowed_within, $not_allowed_within) {
  3. if (isset ($this->_codes[$name])) {
  4. return false; // already exists
  5. }
  6. if (!preg_match ('/^[a-zA-Z0-9*_!+-]+$/', $name)) {
  7. return false; // invalid
  8. }
  9. $this->_codes[$name] = array (
  10. 'name' => $name,
  11. 'callback_type' => $callback_type,
  12. 'callback_func' => $callback_func,
  13. 'callback_params' => $callback_params,
  14. 'content_type' => $content_type,
  15. 'allowed_within' => $allowed_within,
  16. 'not_allowed_within' => $not_allowed_within,
  17. 'flags' => array ()
  18. );
  19. return true;
  20. }
  21. ?>

I jeszcze jedna funkcja, która może pomoże:
  1. <?php
  2. function validate ($action = 'validate') {
  3. if ($action != 'validate' && $action != 'validate_again') {
  4. return false;
  5. }
  6. if ($this->_codeInfo['callback_type'] != 'simple_replace' && $this->_codeInfo['callback_type'] != 'simple_replace_single') {
  7. if (!is_callable ($this->_codeInfo['callback_func'])) {
  8. return false;
  9. }
  10.  
  11. if (($this->_codeInfo['callback_type'] == 'usecontent' || $this->_codeInfo['callback_type'] == 'usecontent?' || $this->_codeInfo['callback_type'] == 'callback_replace?') && count ($this->_children) == 1 && $this->_children[0]->_type == STRINGPARSER_NODE_TEXT) {
  12. // we have to make sure the object gets passed on as a reference
  13. // if we do call_user_func(..., &$this) this will clash with PHP5
  14. $callArray = array ($action, $this->_attributes, $this->_children[0]->content, $this->_codeInfo['callback_params']);
  15. $callArray[] =& $this;
  16. $res = call_user_func_array ($this->_codeInfo['callback_func'], $callArray);
  17. if ($res) {
  18. // ok, now, if we've got a usecontent type, set a flag that
  19. // this may not be broken up by paragraph handling!
  20. // but PLEASE do NOT change if already set to any other setting
  21. // than BBCODE_PARAGRAPH_ALLOW_BREAKUP because we could
  22. // override e.g. BBCODE_PARAGRAPH_BLOCK_ELEMENT!
  23. $val = $this->getFlag ('paragraph_type', 'integer', BBCODE_PARAGRAPH_ALLOW_BREAKUP);
  24. if ($val == BBCODE_PARAGRAPH_ALLOW_BREAKUP) {
  25. $this->_flags['paragraph_type'] = BBCODE_PARAGRAPH_ALLOW_INSIDE;
  26. }
  27. }
  28. return $res;
  29. }
  30.  
  31. // we have to make sure the object gets passed on as a reference
  32. // if we do call_user_func(..., &$this) this will clash with PHP5
  33. $callArray = array ($action, $this->_attributes, null, $this->_codeInfo['callback_params']);
  34. $callArray[] =& $this;
  35. return call_user_func_array ($this->_codeInfo['callback_func'], $callArray);
  36. }
  37. return (bool)(!count ($this->_attributes));
  38. }
  39. ?>


Uporałem się jakoś z tamtymi problemami i doszedłem do czegoś takiego:
  1. <?php
  2. require_once 'bbcode/stringparser_bbcode.class.php';
  3.  
  4. //kontener 
  5. class BBCode{
  6.  
  7. var $bbcode;
  8.  
  9. //konstruktor
  10. public function __construct() {
  11. $this->bbcode = new StringParser_BBCode ();
  12.  
  13. $this->bbcode->setParagraphHandlingParameters ("\n\n", "<p>", "</p>");
  14.  
  15. $this->bbcode->addCode ('b', 'simple_replace', null, array ('start_tag' => '<b>', 'end_tag' => '</b>'),
  16. 'code', array ('block', 'inline'), array ());
  17.  
  18. //PHP
  19. $this->bbcode->addCode ('php', 'callback_replace', array($this, 'callbackPHP'), array ('start_tag' => '<code>', 'end_tag' => '</code>'),
  20. 'code', array ('block', 'inline'), array ());
  21. }
  22. //funkcja kolorujaca kod za pomoca Geshi'
  23. function codeHighlight($str, $lang) {
  24. require_once 'highlight/geshi.php';
  25. $geshi =& new GeSHi($str, $lang);
  26. return $geshi->parse_code();
  27. }
  28. //callbacki
  29. //PHP
  30. public function callbackPHP($action, $attributes, $content, $params, &$node_object) {
  31. echo '#DEBUG: wywolano callback';
  32. return $this->codeHighlight($content, 'cpp');
  33. }
  34.  
  35. }
  36.  
  37.  
  38. //----- MAIN -------
  39. if (!empty($_POST['text'])) {
  40.  
  41. $bbcode = new BBCode();
  42. echo $bbcode->bbcode->parse ($_POST['text']);
  43. }
  44.  
  45. ?>

Jedyny problem jest taki, że callbackPHP() wywołuje się teraz, dwa razy. Skutkom ubocznym częściowo zaradziłem zamieniając rquire... na require_once 'highlight/geshi.php'; ale mimo wszystko funkcja dalej wywołuje się raz niepotrzebnie. Myślę, że powodem jest ten zapis:
  1. <?php
  2. array($this, 'callbackPHP')
  3. ?>

ale nie mam pojęcia jak to zapisać prawidłowo.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.