php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 12.04.2011, 11:12  
Neuer Benutzer
 
Registriert seit: 12.04.2011
Beiträge: 7
PHP-Kenntnisse:
Fortgeschritten
DerJoghurt befindet sich auf einem aufstrebenden Ast
Standard [Erledigt] Unserialize Objekt mit Namespaces und __autoload

Hallo Leute,

ich möchte mir einige Klassen schreiben, um Daten einer API abzufragen und weiter zu verarbeiten. Die API gibt die Daten dabei als SerializedObject aus.

Da ich in meinem Framework (Symfony 2) mit namespaces und einer __autoload-Funktion arbeite, sieht ein vereinfachtes Beispiel folgendermaßen aus:

PHP-Code:
<?php
//index.php
    
use serializestart;

       function 
__autoload($class)
            {    
            echo 
"<h3>Klasse laden</h3>";
                    
$params=explode('\\',$class);
            echo 
"<p>" end($params) . "</p>";
            require_once 
end($params).'.php';
            }
    
$start = new start();
    
$start->init();
?>
PHP-Code:
<?php
//start.php
    
namespace serialize;

    class 
start{
        function 
init(){
            
$mySerializedObject 'O:17:"SerializationTest":3:{s:7:"counter";i:999;s:6:"myName";s:14:"Random Visitor";s:5:"myAge";i:59;}'
            
//Serialize
            
echo var_dump($mySerializedObject). '<br />';
            
//Unserialize
            
$myUnserializedObject unserialize($mySerializedObject);
            echo 
var_dump($myUnserializedObject). '<br />';
        }
    }
?>
PHP-Code:
<?php
//SerializationTest.php
    
namespace serialize;

    class 
SerializationTest
    
{
        public 
$counter;
        public 
$myName;
        public 
$myAge;
    }
?>
Wer das Beispiel ausprobiert, wird merken, dass der String nicht unserialized werden kann, obwohl die Klasse "SerializationTest" nachgeladen wird. Es wird folgendes Objekt ausgegeben:
object(__PHP_Incomplete_Class)#2 (4) { ["__PHP_Incomplete_Class_Name"]=> string(17) "SerializationTest" ["counter"]=> int(999) ["myName"]=> string(14) "Random Visitor" ["myAge"]=> int(59) }

Kennt sich jemand besser mit namespaces aus?
Hat jemand eine Idee, was ich machen kann, um dieses Problem zu lösen?

Vielen Dank,
Jo
DerJoghurt ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 12.04.2011, 12:28  
Benutzer
 
Benutzerbild von sharpx
 
Registriert seit: 12.04.2011
Beiträge: 50
PHP-Kenntnisse:
Fortgeschritten
sharpx befindet sich auf einem aufstrebenden Ast
Standard

Der Wert PHP_Incomplete_Class resultiert darin, dass dein PHP-Skript zu dem Zeitpunkt zu dem du mit unserialize() versuchst, das Objekt "wiederherzustellen", die Klasse SerializationTest nicht kennt.

Hier eine Beschreibung des "typischen Problemauslösers": Auf der Seite Foo1.php wird das Objekt $a aus der Klasse Milchflasche instanziert und mit Werten befüllt. Anschließend wird serialize($a) ausgeführt und der Wert gespeichert. Auf Seite Bla2.php wird soll der gespeicherte String nun mit Hilfe von unserialize() wieder in ein Objekt umgewandelt werden, doch dies schlägt fehl und der Klassenname des Objekts lautet plötzlich "_PHP_Incomplete_Class". Grund hierfür ist, dass der Bauplan des gewünschten Objekts, d.h. die Klassendefinition, zu diesem Zeitpunkt noch nicht geladen war.

In älteren PHP-Versionen konnte man dieses Problem dadurch lösen, dass man die Klassendatei einfach per include() oder require() einbindet. In deinem Fall ist es schätzungsweise zusätzlich notwendig, dass der entsprechende Namespace von SerializationTest eingebunden/benutzt wird.
sharpx ist offline   Mit Zitat antworten
Alt 12.04.2011, 14:06  
Neuer Benutzer
 
Registriert seit: 12.04.2011
Beiträge: 7
PHP-Kenntnisse:
Fortgeschritten
DerJoghurt befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von sharpx Beitrag anzeigen
In älteren PHP-Versionen konnte man dieses Problem dadurch lösen, dass man die Klassendatei einfach per include() oder require() einbindet. In deinem Fall ist es schätzungsweise zusätzlich notwendig, dass der entsprechende Namespace von SerializationTest eingebunden/benutzt wird.
Vielen Dank für deine Hilfe, sharpx.

Wenn ich keine Namespaces verwende und in der start.php die Klasse SerializationTest mit include einbinde, funktioniert auch alles wunderbar. Nur verstehe ich nicht, wie ich das ganze mit Namespaces und __autoload hinbekomme.

Ich habe jetzt versucht meine Funktion __autoload mit eval("namespace serialize;"); zu erweitern:
PHP-Code:
<?php
//index.php
    
use serializestart;

       function 
__autoload($class)
            {    
            echo 
"<h3>Klasse laden</h3>";
                    
$params=explode('\\',$class);
            echo 
"<p>" end($params) . "</p>";
            eval(
"namespace serialize;");
            include_once 
end($params).'.php';
            }
    
$start = new start();
    
$start->init();
?>
Leider funktioniert das so auch nicht. Weiß jemand was ich falsch mache?

LG,
Jo
DerJoghurt ist offline   Mit Zitat antworten
Alt 12.04.2011, 14:50  
Erfahrener Benutzer
 
Registriert seit: 11.04.2011
Beiträge: 260
PHP-Kenntnisse:
Fortgeschritten
lcrash wird schon bald berühmt werden
Standard

__autoload() und vorallem eval() scheinen mir hier ungeeignet zu sein.

http://php.net/unserialize sagt:
Zitat:
Hinweis: Die unserialize_callback_func-Direktive

Es ist möglich, eine Callback-Funktion anzugeben, die aufgerufen wird, wenn eine undefinierte Klasse während des Deserialisierens instanziiert werden soll (um dem Erhalt des unvollständigen object "__PHP_Incomplete_Class" vorzubeugen). Nutzen Sie Ihre php.ini, ini_set() oder .htaccess, um 'unserialize_callback_func' festzulegen. Jedesmal, wenn eine undefinierte Klasse instanziiert werden soll, wird diese Funktion aufgerufen. Um dieses Feature abzuschalten, muss die Einstellung nur ungefüllt sein.
Könnte demnach einfach __autoload() bzw. der Autoloader von Symphony sein.
lcrash ist offline   Mit Zitat antworten
Alt 12.04.2011, 15:16  
Neuer Benutzer
 
Registriert seit: 12.04.2011
Beiträge: 7
PHP-Kenntnisse:
Fortgeschritten
DerJoghurt befindet sich auf einem aufstrebenden Ast
Standard

In meinem Beispiel habe ich das Problem von Symfony und dem Autoloader und der Funktion "unserialize" versucht nachzubauen.
Der Autoloader wird ja auch für die Klasse "SerializationTest" aufgerufen und die Klasse wird includiert aber das scheint nicht zu reichen.

Wenn ich mein kleines Beispiel zum Laufen bekomme, dann bekomme ich das auch mit Symfony hin.
Leider haben mir eure Hinweise noch nicht wirklich weitergeholfen.

Hat jemand noch einen Tipp für mich?
DerJoghurt ist offline   Mit Zitat antworten
Alt 12.04.2011, 15:58  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Was passiert denn wenn du das unserialize ein zweites mal aufrufst? Bekommst du dann wieder ein incomplete class?
cycap ist offline   Mit Zitat antworten
Alt 12.04.2011, 17:15  
Neuer Benutzer
 
Registriert seit: 12.04.2011
Beiträge: 7
PHP-Kenntnisse:
Fortgeschritten
DerJoghurt befindet sich auf einem aufstrebenden Ast
Standard

Ich habe jetzt unserialize ein weiteres Mal eingefügt.
Wenn ich in der Funktion __autoloader "include" einfüge kommt:
Code:
Fatal error: Cannot redeclare class serialize\SerializationTest in /var/www/serialize/SerializationTest.php on line 5
Wenn ich "include_once" aufrufe, dann kommt wieder object(__PHP_Incomplete_Class).
DerJoghurt ist offline   Mit Zitat antworten
Alt 12.04.2011, 17:27  
Benutzer
 
Benutzerbild von sharpx
 
Registriert seit: 12.04.2011
Beiträge: 50
PHP-Kenntnisse:
Fortgeschritten
sharpx befindet sich auf einem aufstrebenden Ast
Standard

Der serialisierte String muss den kompletten Namespacepfad und den Klassennamen enthalten. Also nicht SerializationTest, sondern serialize\SerializationTest.

Hier ein serialisierter String zum Testen:
Code:
'O:38:"serialize\SerializationTest":3:{s:7:"counter";i:42;s:6:"myName";s:5:"Simon";s:5:"myAge";i:16;}'
Das "richtige" Ergebnis:
Code:
serialize\SerializationTest Object ([counter] => 42 [myName] => Simon [myAge] => 16 )
sharpx ist offline   Mit Zitat antworten
Alt 12.04.2011, 17:51  
Neuer Benutzer
 
Registriert seit: 12.04.2011
Beiträge: 7
PHP-Kenntnisse:
Fortgeschritten
DerJoghurt befindet sich auf einem aufstrebenden Ast
Standard

Ja, das funktioniert so. Danke für den Tipp.

Leider bekomme ich den serialisierte String von einer externen API, die ich nicht beeinflussen kann.
Gibt es noch eine andere Möglichkeit oder soll ich den String jeweils abändern?
DerJoghurt ist offline   Mit Zitat antworten
Alt 12.04.2011, 18:03  
Erfahrener Benutzer
 
Registriert seit: 21.12.2004
Beiträge: 5.235
PHP-Kenntnisse:
Fortgeschritten
mepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblickmepeisen ist ein wunderbarer Anblick
mepeisen eine Nachricht über ICQ schicken mepeisen eine Nachricht über Skype™ schicken
Standard

Es gibt keine andere Möglichkeit. Du wirst den String abändern müssen, wenn du die Std-PHP-Serialisierung verwenden willst. Flow3 beispielsweise nutzt eine komplett eigene Serialisierung, da u.U. der Klassenname zur Entwicklungszeit (und in der Datenbank) durch eine speziell angepasste Klasse (ein Proxy) ersetzt wird.

Wieso weiss die externe API nichts von deinen Namespaces?
__________________
www.php-maven.org PHP und Maven vereint: Build/Deploy/Produktion/Konfiguration, Projekt Management, CI, PHPUnit, zahlreiche Frameworks
Twitter @ https://twitter.com/#!/mepeisen und Facebook @ http://t.co/DZnKSUih
mepeisen ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
namespaces und require reliC PHP Einsteiger 3 10.03.2011 08:38
Bestehendes Objekt in einer inkludierten File Nutzen MLang PHP Einsteiger 6 25.02.2011 15:45
Rückgabe von mysql_fetch_object kein Objekt mehr ? Heurazio PHP Einsteiger 8 10.12.2010 13:05
Objekt in Session-Array ablegen mupilz PHP-Fortgeschrittene 2 30.08.2010 17:25
[Erledigt] Problem beim dynamischen Erweitern von Arrays in Object Porperties dille001 PHP Tipps 2010 3 24.05.2010 11:52
Ergebnis einer Datenbankabfrage als Objekt chunky PHP Tipps 2010 7 27.01.2010 21:38
Objekt per Klassenmethode löschen Ti-Systems PHP Tipps 2010 4 20.01.2010 19:28
[Erledigt] Objekt Iteration Löschmethode stayInside PHP-Fortgeschrittene 10 29.11.2009 15:07
Objekt löschen via Methodenübergabe desselben nikosch Software-Design 19 01.06.2009 00:38
[Erledigt] Objekt an Konstruktor übergeben hawkeye78 PHP Tipps 2009 7 28.02.2009 19:01
Objekt im GET-Query wird nicht übertragen Ralpho PHP-Fortgeschrittene 10 05.05.2008 10:03
[Erledigt] PHP5 OOP Zugriff aus einem Objekt auf ein externes Objekt PHP Tipps 2006 5 28.01.2006 16:05
Objekt übergeben Fatal Error PHP Tipps 2007 5 28.12.2005 14:43
kann sich ein Objekt selbst serialisieren? ajo_silent PHP Tipps 2005-2 24 27.06.2005 09:13
Immer noch Probleme mit serialize und unserialize PHP-Fortgeschrittene 13 15.08.2004 13:15

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
serialize namespace php, php unserialize object, php serializable namespace, __php_incomplete_class_name], php unserialize fatal error instead of incomplete class, php klasse aus string namespace wird nicht erkannt, php serialize namepsace classes, unserialize_callback_func namespace, php unserialize namespaced classes, php unserialize __php_incomplete_class, php incomplete class why auto unserialized, session namespace, symfony2 unserialize, symfony2 namespace anzeigen, unserialize_callback_func .htaccess beispiel, unserialize php beispiel, php object name namespace, php fatal error: cannot redeclare unserialize, php unseralize object autoloader, php eval namespace

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:33 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum