Autor | Zpráva | ||
---|---|---|---|
scorapka Profil |
#1 · Zasláno: 2. 11. 2013, 22:14:38 · Upravil/a: scorapka
Dobrý den,
koupil jsem si knihu Programujeme vlastní e-shop v PHP 5, Michael Peacock http://knihy.cpress.cz/programujeme-vlastni-e-shop.html Stáhl jsem si zdrojové kody příkladů. Vložil do svého adresáře www. Vytvořil databázi a udělal vše co je v souboru ČTIMNE.txt Po spuštění vyskakují chyby: Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Můžete také vyzkoušet ale prosím co znamená tato chyba? Děkuji. zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu: Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 tady je ta chybná funkce, co hlásí chybu, že není statická... public function buildFromTemplates() { $bits = func_get_args(); $content = ""; foreach( $bits as $bit ) { if( strpos( $bit, 'views/' ) === false ) { $bit = 'views/' . PHPEcommerceFrameworkRegistry::getSetting('view') . '/templates/' . $bit; } if( file_exists( $bit ) == true ) { $content .= file_get_contents( $bit ); } } $this->page->setContent( $content ); } |
||
scorapka Profil |
#2 · Zasláno: 3. 11. 2013, 10:22:24
tak díky za pomoc:(
|
||
Tori Profil |
scorapka:
„zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu:“ To je ale jiná chyba z úplně jiné třídy, ne? Varianta 1: Jak vypadá ta metoda getSetting ? Potřebuje / využívá na něco instanci Registry ?
Varianta 2: jak vypadá třída Registry ? Logicky bych podle názvu čekala, že to bude singleton, a tedy bude mít nějakou metodu Registry::getInstance() - má, nemá?
Kdyžtak se někdy k večeru kouknu na ty zdrojáky. |
||
scorapka Profil |
#4 · Zasláno: 3. 11. 2013, 11:36:17 · Upravil/a: scorapka
Tori:
„zkoušel jsem nastavit metodu na statickou (public static) ale nepomáha, dále to píše chybu: To je ale jiná chyba z úplně jiné třídy, ne?“ ano další chyba to je úplně jiné třídy. Abych byl konkrétnější, hodím sem úplný výpis chyb: Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Notice: Uninitialized string offset: 36 in C:\www\ecom\models\basket\model.php on line 163 Notice: Undefined variable: weightFound in C:\www\ecom\models\basket\model.php on line 127 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 132 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 33 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getSetting() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 180 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\page.class.php on line 130 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 111 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 78 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 83 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 139 Strict Standards: Non-static method PHPEcommerceFrameworkRegistry::getObject() should not be called statically, assuming $this from incompatible context in C:\www\ecom\registry\objects\template.class.php on line 139 Varianta 1: /** * Vrátí nastavení z registru * @param String $key klíč použitý pro uložení nastavení * @return String nastavení */ public function getSetting( $key ) { return self::$settings[ $key ]; } Varianta 2: Třída registry má singleton /** * metoda singleton pro přístup k objektu * @access public * @return */ public static function singleton() { if( !isset( self::$instance ) ) { $obj = __CLASS__; self::$instance = new $obj; } return self::$instance; } Hodím ti sem celou třídu registry.class.php <?php /** * The PCARegistry object * Implements the Registry and Singleton design patterns * Building a PHP Ecommerce Framework * * @version 1.0 * @author Michael Peacock */ class PHPEcommerceFrameworkRegistry { /** * pole objektů uložených v registru * @access private */ private static $objects = array(); /** * pole nastavení uložených v registru * @access private */ private static $settings = array(); /** * instance registru * @access private */ private static $instance; private static $urlPath; private static $urlBits = array(); /** * Soukromý konstrutkor zabrání přímému vytvoření * @access private */ private function __construct() { } /** * metoda singleton pro přístup k objektu * @access public * @return */ public static function singleton() { if( !isset( self::$instance ) ) { $obj = __CLASS__; self::$instance = new $obj; } return self::$instance; } /** * zabrání kolonování objektu: vyvolá chybu E_USER_ERROR */ public function __clone() { trigger_error( 'Klonování registru není povoleno', E_USER_ERROR ); } /** * Uloží objekt do registru * @param String $object název objektu * @param String $key klíč do pole * @return void */ public function storeObject( $object, $key ) { if( strpos( $object, 'database' ) !== false ) { $object_a = str_replace( '.database', 'database', $object); $object = str_replace( '.database', '', $object); require_once('databaseobjects/' . $object . '.database.class.php'); $object = $object_a; } else { require_once('objects/' . $object . '.class.php'); } self::$objects[ $key ] = new $object( self::$instance ); } /** * Vrátí objekt z registru * @param String $key klíč do pole použitý při uložení objektu * @return object - objekt */ public function getObject( $key ) { if( is_object ( self::$objects[ $key ] ) ) { return self::$objects[ $key ]; } } /** * Uloží nastavení do registru * @param String $data the setting we wish to store * @param String $key klíč pro přístup k nastavení * @return void */ public function storeSetting( $data, $key ) { self::$settings[ $key ] = $data; } /** * Vrátí nastavení z registru * @param String $key klíč použitý pro uložení nastavení * @return String nastavení */ public function getSetting( $key ) { return self::$settings[ $key ]; } /** * Vrátí data z aktuální adresy URL * @return void */ public function getURLData() { $urldata = (isset($_GET['page'])) ? $_GET['page'] : '' ; self::$urlPath = $urldata; if( $urldata == '' ) { self::$urlBits[] = 'home'; self::$urlPath = 'home'; } else { $data = explode( '/', $urldata ); while ( !empty( $data ) && strlen( reset( $data ) ) === 0 ) { array_shift( $data ); } while ( !empty( $data ) && strlen( end( $data ) ) === 0) { array_pop($data); } self::$urlBits = $this->array_trim( $data ); } } public function redirectUser( $urlPath, $header, $message, $admin = false) { self::getObject('template')->buildFromTemplates('redirect.tpl.php'); self::getObject('template')->getPage()->addTag( 'header', $header ); self::getObject('template')->getPage()->addTag( 'message', $message ); if( $admin != true ) { self::getObject('template')->getPage()->addTag('url', $urlPath ); } else { // } } public function getURLBits() { return self::$urlBits; } public function getURLBit( $whichBit ) { return self::$urlBits[ $whichBit ]; } public function getURLPath() { return self::$urlPath; } private function array_trim( $array ) { while ( ! empty( $array ) && strlen( reset( $array ) ) === 0) { array_shift( $array ); } while ( !empty( $array ) && strlen( end( $array ) ) === 0) { array_pop( $array ); } return $array; } } ?> |
||
Tori Profil |
Buď můžete všechna volání
PHPEcommerceFrameworkRegistry::getNěco() a PHPEcommerceFrameworkRegistry::storeNěco()
přepsat na PHPEcommerceFrameworkRegistry::singleton()->getNěco() , anebo metody getSettings , storeSettings , getObject a storeObject změnit na statické. První možnost je bez problémů použitelná hned. U té druhé by bylo potřeba nejdřív ověřit v celém kódu eshopu, jestli se ty metody někde nevolají i na instanci (např. nechat vyhledat řetězec "->getSettings" ).
Je to docela hloupé, že ke knížce jsou zdrojáky, které generují chyby. E_STRICT bych ještě přežila, to může být i rokem napsání anglické verze knihy, ale E_NOTICE by tam už být nemělo. pozn. ve [#3] jsem se ptala kvůli těmto dvěma možnostem, jen v opačném pořadí. |
||
scorapka Profil |
#6 · Zasláno: 3. 11. 2013, 21:31:49
Tori:
tak jsem ve tříde template.class.php přpsal ty volání (přidal singleton()->) chyby to už nepíše. Super. Takže díky moc za pomoc. Ale ještě to hlásí tyhle chyby: Notice: Undefined variable: weightFound in C:\www\ecom\models\basket\model.php on line 127 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined offset: 0 in C:\www\ecom\models\basket\model.php on line 132 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\page.class.php on line 130 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 78 Notice: Undefined offset: 0 in C:\www\ecom\registry\objects\template.class.php on line 83 Notice: Undefined variable: filterSQL in C:\www\ecom\controllers\products\controller.php on line 222 Notice: Uninitialized string offset: 36 in C:\www\ecom\models\basket\model.php on line 163 Co tam jsou zase za chyby? |
||
Tori Profil |
Koukla jsem na to zběžně, bez phpdoc to teda není úplně intuitivní. V models\basket\model.php se na ř.90+100 provádí zřejmě tentýž SQL dotaz dvakrát, ale chybu to nezpůsobí.
- models\basket\model.php:127 - Jelikož se musí sčítat váha všech produktů, tak by asi na ř.126 mělo být $weightFound = false; .
- models\basket\model.php:129+132 - Tohle vypadá, že metoda getShippingWeightCosts vrací prázdné pole. Asi si musíte nejdřív někde v backoffice nastavit alespoň jeden typ poplatků podle váhy zásilky (např. minimálně 0 kg, poplatek 0 Kč.)
- registry\objects\page.class.php:130 - Zkontrolujte si, odkud se to volá, jaká šablona a jaký blok je z ní požadován, jestli není někde v šabloně překlep. Asi by to šlo vyřešit výchozí hodnotou, pokud tag není nalezen:
if (preg_match ('#<!-- START '. $tag . ' -->(.+?)<!-- END '. $tag . ' -->#si', $this->content, $tor) { $tor = str_replace ('<!-- START '. $tag . ' -->', "", $tor[0]); $tor = str_replace ('<!-- END ' . $tag . ' -->', "", $tor); return $tor; } else { return ''; } return preg_match('#<!-- START '.$tag.' -->(.+?)<!-- END '.$tag.' -->#si', $this->content, $tor) ? $tor[1] : ''; - registry\objects\template.class.php:78+83 - najděte si volání metod addTag a/nebo addPPTag (asi to bude zapsané jako PHPEcommerceFrameworkRegistry::singleton()->getObject('page')->addTag ) a zkontrolujte, co se tam posílá za data. Jako druhý parametr by mělo jít nějaké pole, zřejmě není v očekávaném tvaru, chybné klíče jednotlivých prvků apod. Případně pokud je klíč $data[0] nepovinný, tak změňte podmínku na ř.75 na: if (is_array($data) && isset($data[0])) {
- controllers\products\controller.php:222 - to má být zřejmě $this->filterSQL . V kódech k angl.originálu je to taky blbě.
- models\basket\model.php:163 - změňte ten řádek na $string .= $characters[mt_rand(0, strlen($characters)-1 )]; - Autor zapomněl, že ofset posledního bajtu v řetězci je o 1 menší, než délka řetězce.
No, přeju hodně štěstí při dohledávání a opravách dalších chybek. Většina z toho jsou jen maličkosti (spoléhání na existenci indexu v poli apod.), ale některé jsou docela hloupé chyby. To je ale IMHO vina nakladatele, resp. odborného redaktora, který by ten kód měl nejen projít a zkontrolovat syntax+překlad, ale i spustit a vyzkoušet. |
||
scorapka Profil |
#8 · Zasláno: 4. 11. 2013, 11:46:21
Tori:
Tak jsem to začal ladit. Ale přesně nechápu jak myslíš tohle: - models\basket\model.php:129+132 - Tohle vypadá, že metoda getShippingWeightCosts vrací prázdné pole. Asi si musíte nejdřív někde v backoffice nastavit alespoň jeden typ poplatků podle váhy zásilky (např. minimálně 0 kg, poplatek 0 Kč.) Jsem začátečník a neumím si představit jak se nastavuje v backofficu ty poplatky. Máš na mysli v phpmyadminu, a nastavit v databazi ecom? a toto: - controllers\products\controller.php:222 - to má být zřejmě $this->filterSQL. V kódech k angl.originálu je to taky blbě. máš na mysli nahradit if( $filterSQL == '' ) tímhle tím if( $this->filterSQL )
Jinak ti chci poděkovat za tvoji laskavost, že si mi pomohla opravit ty chybné kody. |
||
Tori Profil |
Ad $filterSQL: ano, přesně tak,
if ($this->filterSQL == '') . Když si projdete tu třídu, tak někde se tam do proměnné $this->filterSQL nastavuje nějaké omezení, předpokládala jsem teda, že se to týká i této metody.
K příplatkům za váhu zásilky - mělo by se to nastavit někde v tom eshopu. Ale můžete i přímo přidat 1 řádek do databáze. Zkuste spustit v phpmyadmin tohle, snad by to mělo být správně. INSERT INTO `shipping_costs_weight` (`ID`, `shipping_id`, `lower_weight`, `cost`) VALUES (1, 1, 0.0, 0.0); |
||
scorapka Profil |
#10 · Zasláno: 4. 11. 2013, 12:20:12
Tori:
Tak už se mi podařilo:) jak nahrát do databáze poplatky, tak i přidat if ($this->filterSQL == '') děkuji ti!
Jenže ta ukázka e-shopu má nekonečně mnoho chyb. Ještě to vypisuje tohle: Notice: Undefined variable: currentWeight in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined index: in C:\www\ecom\models\basket\model.php on line 129 Notice: Undefined variable: currentWeight in C:\www\ecom\models\basket\model.php on line 132 Notice: Undefined index: in C:\www\ecom\models\basket\model.php on line 132 Notice: Array to string conversion in C:\www\ecom\registry\objects\template.class.php on line 92 |
||
Tori Profil |
#11 · Zasláno: 4. 11. 2013, 12:43:25
Ty první dvě chyby (
models\basket\model.php:129+132 ) by to vypisovat rozhodně nemělo. Nepřepsal jste si ten řádek, kde je definovaná výchozí hodnota 0? Měly by tam (po předchozí změně) být dva řádky: $currentWeight = 0; $weightFound = false; while( $weightFound == false ) ...
Tu druhou chybu jsem asi způsobila svou radou, nekoukla jsem se na druhou část podmínky. Asi teda bude lepší tohle: if( is_array( $data ) ) { if( isset($data[0]) && $data[0] == 'SQL' ) { // jedná se o výsledek dotazu uložený v mezipaměti, značky se nahradí tímto výsledkem $this->replaceDBTags( $tag, $data[1] ); } elseif( isset($data[0]) && $data[0] == 'DATA' ) { // jedná se o data uložená v mezipaměti, značky se nahradí daty z mezipaměti $this->replaceDataTags( $tag, $data[1] ); } } |
||
scorapka Profil |
#12 · Zasláno: 4. 11. 2013, 14:05:26
Tori:
tak to se omlouvám, zapomněl jsem tam přidat $currentWeight = 0; , to byla zase moje chyba:)
nicméně ještě jsou tam chyby: Warning: Illegal string offset 'weight' in C:\www\ecom\models\basket\model.php on line 130 Warning: Illegal string offset 'cost' in C:\www\ecom\models\basket\model.php on line 133 |
||
Tori Profil |
#13 · Zasláno: 4. 11. 2013, 14:33:26
Tohle zvládnete opravit. ;)
„Illegal string offset 'weight'“ znamená, že se někdo pokouší použít klíč "weight" u proměnné, která není pole, ale řetězec. Takže se kouknete, že proměnná $shippingCosts je naplněná pomocí metody getShippingWeightCosts . V téhle metodě, která má vracet různé typy doplatků podle váhy zboží, se vytváří pole v jiném tvaru, než jaký je očekáván na ř.130. Máte teda dvě nesourodé varianty toho pole a musíte to sjednotit na jednu z nich. Dejte si vyhledat v celém eshopu, kde všude se volá metoda getShippingWeightCosts , koukněte se, jak se s tou návratovou hodnotou pracuje (tj. kterou z těch dvou možností, dvou způsobů uspořádání pole, očekává). Podle toho se pak rozhodněte:
A - metoda getShippingWeightCosts se buď jinde nepoužívá, anebo se tam taky počítá se stejnou strukturou pole, jako v místě, kde vám to hlásilo chyby. --> přepíšte metodu getShippingWeightCosts tak, aby vracela pole v jiném tvaru
B1 - na ostatních místech, kde se volá metoda getShippingWeightCosts , se pracuje s tou strukturou pole, kterou ona skutečně vrací. --> přepíšete tuhle část metody checkBasket , aby pracovala s jiným tvarem pole.
Ale tohle řešení by bylo dost obtížné, takže je možnost B2: --> přidáte další metodu, která použije stejný SQL dotaz jako getShippingWeightCosts , ale bude vracet pole v jiném tvaru.
|
||
scorapka Profil |
#14 · Zasláno: 4. 11. 2013, 17:53:45 · Upravil/a: scorapka
Tori:
No já jsem fakt úplný začátečník, takže jsem hledal metodu getShippingWeightCosts v celém eshopu a nikde jinde není, jen v C:\www\ecom\models\basket\model.php na řádku 358
Nevím jak hledáte efektivněji ale já musel otevírat v PSPpadu každý soubor zvlášt a prohledávat zda tam není. Chci si zvolit způsob A přepsat metodu getShippingWeightCosts , tak aby vracela pole ve správném tvaru. ale fakt netuším jak to udělat:(že by to nemělo vracet Pole array()? Notice: Undefined property: Basket::$isChecked in C:\www\ecom\controllers\basket\controller.php on line 62 |
||
scorapka Profil |
#15 · Zasláno: 5. 11. 2013, 11:26:08
Tori:
Tak jsem na to ještě nepřišel...jinak ti děkuji, že si mi pomáhala Tori. |
||
Tori Profil |
V PSPadu nevím, používám NetBeans a tam se dá hledat ve vybraných adresářích.
K tomu poli: (všechno se týká jen \models\basket\model.php, a předpokládám, že v tabulce shipping_costs_weight jsou data: ID | shipping_id | lower_weight | cost | 1 | 1 | 0.0 | 0.0 | 2 | 1 | 15.0 | 20.0 | Podle toho, jak se na ř.129 pracuje s polem $weightCosts , by mělo mít strukturu
array( 0 => array( 'weight' => 15.0, 'cost' => 20.0, ), 1 => array( 'weight' => 0.0, 'cost' => 0.0, ), ) getShippingWeightCosts vrací pole ve tvaru:
array( 15.0 => 20.0, 0.0 => 0.0, ) getShippingWeightCosts takto:
$shipping_weights_sql = "SELECT cost, lower_weight FROM shipping_costs_weight WHERE shipping_id={$this->shippingMethodID} ORDER BY lower_weight DESC"; $this->registry->getObject('db')->executeQuery( $shipping_weights_sql ); $weights = array(); while( $data = $this->registry->getObject('db')->getRows() ) { $weights[] = array('weight' => $data['lower_weight'], 'cost' => $data['cost']); } return $weights; // dopravné: dle váhy // $currentWeight = 0; -- tohle není potřeba, smazat // $weightFound = false; -- tohle taky foreach ($weightCosts as $weight => $cost) { if( $contents['product_weight'] >= $weight ) { $this->shippingCost = $this->shippingCost + ( $cost * $contents['product_quantity'] ); break; } } |
||
scorapka Profil |
#17 · Zasláno: 5. 11. 2013, 18:16:30
Tori:
ahaaaaa, už to chápu Super, už to funguje, děkuji:) ale ted se snažím odstranit poslední chybu, se kterou si opět nevím rady:( chyba se vypíše při přidání produktu do košíku, a jak je vidět, košík nefunguje jak má... Notice: Undefined property: Basket::$isChecked in C:\www\ecom\controllers\basket\controller.php on line 62
|
||
Tori Profil |
Koukněte do toho modelu, ona se totiž ta proměnná jmenuje trochu jinak.
↓A jo, díky za opravu, ona je to vlastně soukromá vlastnost. |
||
Rfilip Profil |
62, 130 a 156 řádek souboru C:\www\ecom\controllers\basket\controller.php má být:
if( ! $this->basket->isChecked() == true ) { $this->basket->checkBasket(); } |
||
scorapka Profil |
#20 · Zasláno: 5. 11. 2013, 19:59:49
Tak Vám oběma děkuji:) chyba ischecked je vyresena...
ale stejně nejde přidat více jak jedna položka do košíku...což je divné... teď se snad bude s tím kodem pomocí knihy lépe pracovat, když to ted "zatím" nehlásí zadné chyby. |
||
Časová prodleva: 10 let
|
0