Tag Archives: symfony

Symfony1.4 and Doctrine1.2 setting and getting child elements in execution time

Question

I’m using Symfony1.4 and Doctrine1.2 to create children objects and print them in execution time. The problem is that I always get the children objects from the first query.

I have the following schema:

1
2
3
4
5
6
7
8
Parent:
  id
  name

Child:
  id
  parent_id
  name

My operations:

  1. Initially I have one Parent (with id=1), and no Child
  2. I grab a Parent (id=1) and store that object on $parent
  3. List it’s Child objects
  4. Result: none OK: as expected
  5. Create a new Child and set it’s parent to 1
  6. List $parent‘s Child objects
  7. Result: none OOPS: I expected the new Child from 5.!

Code:

1
2
3
4
5
6
$parent = Doctrine_Query::create()->from('Parent p')->where('p.id = ?', 1)->limit(1)->fetchOne(); /* from 2. */
print_r($parent->getChild()->toArray()); /* from 3. */
$child = new Child();
$child->setParentId($parent->getId());
$child->save(); /* from 4. */
print_r($parent->getChild()->toArray()); /* from 6. */

Note, from Doctrine’s comments:

1
2
3
4
5
6
7
8
9
10
11
/**
* refresh
* refresh internal data from the database
*
* @param bool $deep                        If true, fetch also current relations. Caution: this deletes
*                                          any aggregated values you may have queried beforee
*
* @throws Doctrine_Record_Exception        When the refresh operation fails (when the database row
*                                          this record represents does not exist anymore)
* @return boolean
*/

I’ve already tried re-grabbing the $parent before the last line, but the result is the same.

Own Answer

I found a work-around for this issue:

1
2
3
4
5
6
7
$parent = Doctrine_Query::create()->from('Parent p')->where('p.id = ?', 1)->limit(1)->fetchOne();
print_r($parent->getChild()->toArray());
$child = new Child();
$child->setParentId($parent->getId());
$child->save();
$parent->refresh(true); /* see note! */
print_r($parent->getChild()->toArray());

http://stackoverflow.com/questions/18859509/symfony1-4-and-doctrine1-2-setting-and-getting-child-elements-in-execution-time

optimization-icon

Doctrine 1.2 (Symfony 1.4) performance tips & tricks

Sure Doctrine is awesome, but sometimes (every time?), it is also a memory killer. Hopefully there are some handy tricks that can be used on several occasions. Here are some Doctrine 1.2 performance tips & tricks I’ve collected over the time working with Symfony 1.4. Hope they’re useful to you guys!

If you know more performance tips, please leave them in the comments.

 

 

Tip #1

Create a task environment to run tasks and disable the profiler on databases.yml:

1
2
3
4
task:
  doctrine
:
    param
:
      profiler
: false

 

Tip #2

Enable Doctrine’s auto free query objects

1
Doctrine_Manager::connection()->setAttribute(Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS, true);

 

Tip #3

Free Doctrine objects when they are no longer needed

1
2
$doctrine_object->free(true);
$doctrine_object = null;

 

Tip #4

Force Doctrine connection clear after performing needed Doctrine operations

1
2
3
4
5
6
7
Doctrine_Manager::connection()->connect();

// code code ...
$doctrine_object = Doctrine_Query::create()->from('Modal a')->limit(1)->fetchOne();
// code code...

Doctrine_Manager::connection()->clear();

 

Tip #5

Hydrate array when Model objects are not needed.

1
$doctrine_object = Doctrine_Query::create()->from('Modal a')->limit(1)->execute(array(), Doctrine_Core::HYDRATE_ARRAY);

 

Tip #6

Enable APC caching on Doctrine queries.

1
2
Doctrine_Manager::connection()->setAttribute(Doctrine::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc(array('prefix' => 'fancyapcprefix_')));
Doctrine_Manager::connection()->setAttribute(Doctrine_Core::ATTR_RESULT_CACHE, new Doctrine_Cache_Apc(array('prefix' => 'fancyapcprefix_')));

 

Tip #7

Perform bulk inserts instead of one-by-one inserts.

1
2
3
4
5
6
7
8
9
10
11
$record1 = new Model()
$record1->setName('Example #1');
$record2 = new Model()
$record2->setName('Example #2');

$col = new Doctrine_Collection('Model');
$col->add($record1);
$col->add($record2);
$col->add($record3);
$col->add($recordN);
$col->save();

from this post

 

You can read more on Doctrine 1.2 performance here, here, here and here.

Nginx Symfony 1.4 Configuration

We’ve been trying out nginx server for symfony 1.4 applications, the configuration can be a little bit tricky though… Here’s a working example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
server {
  listen 80;
 
  server_name yourdomain.com www.yourdomain.com;

  root /var/www/yourdomain.com/httpdocs/web;

  access_log /var/www/yourdomain.com/logs/access_log main;
  error_log /var/www/yourdomain.com/logs/error_log;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php$uri?$args;
  }
 
  location ~ "^(.+\.php)($|/)" {
        fastcgi_split_path_info ^(.+\.php)(.*)$;
 
        fastcgi_param PHP_VALUE "error_log=/var/www/yourdomain.com/logs/error_log";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_pass   127.0.0.1:9000;
        include        fastcgi_params;
    }

}

Form choice filter auto sort by name

The following snippet will auto-sort all sfWidgetFormDoctrineChoice elements on symfony filters.

On BaseFormFilterDoctrine.class.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
abstract class BaseFormFilterDoctrine extends sfFormFilterDoctrine
{

    public function setup()
    {
        $guesses = array('name', 'title', 'description', 'subject', 'keywords', 'id');

        foreach ($this->getWidgetSchema()->getFields() as $f)
        {
            if ($f instanceof sfWidgetFormDoctrineChoice)
            {
                $model = $f->getOption('model');
                $table = Doctrine::getTable($model);
                $order_by = null;
                foreach ($guesses as $descriptionColumn)
                {
                    if ($table->hasColumn($descriptionColumn))
                    {
                        $order_by = $descriptionColumn;
                        break;
                    }
                }
               
                if (isset($order_by) && $order_by)
                {
                    $f->setOption('order_by', array($order_by, 'asc'));
                }
            }
           
        }

    }

}

Debugging doctrine:data-load

I know it drives you MAD when you try to load a bunch of features and get an error like:

1
SQLSTATE[23000]: Integrity CONSTRAINT violation: 1062 Duplicate entry '16' FOR KEY 'PRIMARY'

Luckily there’s an undocumented argument on doctrine’s data-load task:

–trace

1
2
3
4
5
6
7
8
9
10
$ php symfony doctrine:data-load --trace

>> doctrine Loading data fixtures from "/home/bla/public_html/site/data/fixtures"
>> doctrine Loading data fixtures from "/home/bla/public_html/site/plugins/sfDoctrineGuardPlugin/data/fixtures"
>> Doctrine_Connection_Mysql exec : SET NAMES 'UTF8' - ()
>> Doctrine_Connection_Mysql exec : DELETE FROM table_a - ()
>> Doctrine_Connection_Mysql exec : DELETE FROM table_b - ()
>> Doctrine_Connection_Mysql exec : DELETE FROM sf_guard_user - ()
>> Doctrine_Connection_Statement execute : INSERT INTO sf_guard_user (algorithm, is_active, is_super_admin, first_name, last_name, email_address, username, salt, password, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - (sha1, 1, 1, bla, blah, blah@adclick.pt, blah, blah48ca1e4247258a0ec29f9d1aac8, blah32ed46c3a74deebb071456114e4406eba42e, 2012-01-12 18:07:02, 2012-01-12 18:07:02)
...