Showing posts with label symfony. Show all posts
Showing posts with label symfony. Show all posts

Monday, 30 August 2010

Symfony 'String could not be parsed as XML'

I was receiving this error on my symfony project (using the sfWhoIsOnline plugin):

[28-Aug-2010 21:50:54] PHP Fatal error:  Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /home/xxxxxxx/plugins/sfWhoIsOnlinePlugin/lib/sfWhoIsOnlineUserFacade.class.php:38
Stack trace:
#0 /home/xxxxxxx/plugins/sfWhoIsOnlinePlugin/lib/sfWhoIsOnlineUserFacade.class.php(38): SimpleXMLElement->__construct('')
#1 /home/xxxxxxx/plugins/sfWhoIsOnlinePlugin/lib/filter/sfWhoIsOnlineFilter.class.php(14): sfWhoIsOnlineUserFacade::registerUser(Object(myUser))
#2 /home/xxxxxxx/cache/frontend/prod/config/config_core_compile.yml.php(1026): sfWhoIsOnlineFilter->execute(Object(sfFilterChain))
#3 /home/xxxxxxx/plugins/sfDoctrineGuardPlugin/lib/sfGuardRememberMeFilter.class.php(56): sfFilterChain->execute()
#4 /home/xxxxxxx/cache/frontend/prod/config/config_core_compile.yml.php(1026): sfGuardRememberMeFilter->execute(Object(sfFilterChain))
#5 /home/xxxxxxx/cache/frontend/prod/config/config_core_compile.yml.php(990): sfFilterChain->execute()
#6 /home/xxxxxxx/cache/frontend/prod/config/config_core_compile.yml.php(1026): sfRenderingFilt in /home/xxxxxxx/plugins/sfWhoIsOnlinePlugin/lib/sfWhoIsOnlineUserFacade.class.php on line 38
[29-Aug-2010 00:06:48] String could not be parsed as XML
[29-Aug-2010 02:14:47] String could not be parsed as XML

Turns out, SimpleXMLElement can't handle empty strings or badly encoded documents well. As a patch of sorts, I replaced the code at line 38 in the sfWhoIsOnlineUserFacade class with the following lines (original lines in bold):

/* Begin Hack to fix error 'String could not be parsed as XML' */
try {
  $xml = new SimpleXMLElement($xmlString);    // <-- Original line 38   
$instance->fromXml($xml);                // <-- Original line 39
} catch (Exception $e) {
  sfContext::getInstance()->getLogger()->crit('sfWhoIsOnline failed to create SimpleXMLElement');
  sfContext::getInstance()->getLogger()->crit('xmlString: '.$xmlString);
}
/* End Hack */

References:
http://drupal.org/node/541892
http://weierophinney.net/matthew/archives/111-mbstring-comes-to-the-rescue.html
http://www.google.com/search?hl=en&q=String+could+not+be+parsed+as+XML&aq=f&aqi=&aql=&oq=&gs_rfai=
http://ketarin.canneverbe.com/forum/viewtopic.php?id=384

Thursday, 24 June 2010

Symfony / sfGuardUser: MySQL errno: 150 Failing Query "ALTER TABLE sf_guard_user......."

I've been trying to link up my symfony project (using Doctrine) to sfGuardPlugin with profiles. However, when trying to rebuild the schema and insert sql, I encountered the following error:

SQLSTATE[HY000]: General error: 1005 Can't create table 'phoenix.#sql-740_d7' (errno: 150). Failing Query: "ALTER TABLE sf_guard_user_profile ADD CONSTRAINT sf_guard_user_profile_user_id_sf_guard_user_id FOREIGN KEY (user_id) REFERENCES sf_guard_user(id)". Failing Query: ALTER TABLE sf_guard_user_profile ADD CONSTRAINT sf_guard_user_profile_user_id_sf_guard_user_id FOREIGN KEY (user_id) REFERENCES sf_guard_user(id)


This isn't an incredibly useful error message. Turns out that it's to do with the way MySQL handles cascading constraints. To cut a long story short, there's more info in the links posted below, but basically you need to remember that "type: integer" does not mean it will be stored as INTEGER in MySQL. As a matter of fact, "type: integer" in a schema.yml file translates into a "BIGINT(20)" in MySQL - which means when you add a constraint to a normal INTEGER field, it fails.

To store an integer value in schema.yml, use "type: integer(4)". This will translate into a type of INTEGER in MySQL.

Explained in a comment I found:
Something you might be interested in, that took me quarter an hour. integer(11) in schema.yml does not result in int(11) in MySQL, but instead you have to write integer(4) in your schema.yml. integer integer int/serial integer(1) tinyint smallint/serial integer(2) smallint smallint/serial integer(3) mediumint int/serial integer(4) int int/serial integer(5) bigint bigint/bigserial However, in my case integer without a number resulted in BIGINT.


More info:
http://trac.symfony-project.org/wiki/sfGuardPluginExtraDocumentation
http://mirmodynamics.com/post/2009/04/02/SQLSTATE%5BHY000%5D%3A-General-error%3A-1005-Can-t-create-table-*-%28errno%3A-150%29 (especially see the last comment)
http://bytes.com/topic/mysql/answers/865699-cant-create-table-errno-150-foreign-key-constraints