3

Something I haven't seen a lot of on Google search or anything is questions about PHPs max class handling at runtime.

Say I have a custom arrayaccess class that could house upto 8k objects of type "User".

Since the arrayaccess class does not allow me to do:

$d[0]->username = "sam"

And set the class only for a residual object like I can in iterator when you do a foreach() each loop brings out an object but the array itself has got no objects in, it just assigns a new populated object (allowing you to reuse the same spot in memory over and over) in each loop of the array. I can only set a object in the offsetGet() method within the offset of the array within the arrayaccess class. Due to this I would need to house anything upto 8K objects at any one point within this arrayaccess class (maybe even 20k objects).

So each offset in my arrayaccess class could be an object of say "User" and there could be upto 20k of them (8k at least).

My Question is: Would PHP be able to handle this amount of class instances? I mean this is a lot of classes and I am worried it could easily ruin my memory consumption.

hakre
  • 193,403
  • 52
  • 435
  • 836
Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • 5
    that's a lot of *objects*, not a lot of classes – Karoly Horvath Jul 25 '11 at 10:02
  • Since PHP is usually used for web applications - i.e. each invocation of PHP is for a specific user request, why would you need 8000+ 'user' objects? – symcbean Jul 25 '11 at 12:34
  • Im doing it for subdocuments on a MongoDB activeRecord, for example: you can have a subdocument of "posts" within "thread". Im trying to work out the best way to allow that subdocument to be assigned to a class but without using too much memory – Sammaye Jul 25 '11 at 13:23

4 Answers4

6

You are talking about objects and not classes.

PHP has no problem dealing with a lot of objects, but if there is an issue just increase the memory_limit in php.ini.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • Well, it's probable that the script will also timeout if that many objects need to be created. http://codepad.org/25j2dfUb – Jared Farrish Jul 25 '11 at 10:12
  • @Jared: nahh.. that will finish within a second – Karoly Horvath Jul 25 '11 at 10:15
  • Ok Kool thanks. Yea tbh one thing I am worried is that I would have to expand PHPs memory above 1gb for many concurrent users before scaling requires me to (meaning my site many require more money before it would need to when using a different approach). But if PHP is designed to be able to hold that amount nicely and in a orderly fashion then hopefully should have nothing to worry about :). thanks. – Sammaye Jul 25 '11 at 10:20
  • @Jared you are right on 20k is does choke the script quite hard, hmm – Sammaye Jul 25 '11 at 10:23
  • it's very quick here with 100k objects, of course it depends on how much stuff you store in your objects. – Karoly Horvath Jul 25 '11 at 10:28
  • Yea as @hakre states it is based upon the object. Ima go off and do some testing (shrink my embeddedDocument Object down), I'll report back with an answer and points when I am done :) – Sammaye Jul 25 '11 at 10:33
  • @Sammaye - I would think your processor speed and memory read times would affect the timeout. – Jared Farrish Jul 25 '11 at 14:41
  • I decided to go with a hybrid method of saying f*** it and using residual objects to keep myself under 5 meg ram per request. Thanks :) – Sammaye Jul 25 '11 at 14:44
2

The amount of classes that you can instantiate (objects) is normally bound by the memory limit. So it depends how much memory is consumed by each object and the total number of objects.

So you actually need to test how much memory your objects will consume. I've put together a little test for demonstration purposes. That one shows that more of 439 000 instances of (small) stdClass object instances are possible with a 128m memory limit:

$store = array();
$max = 500001;
for($i = 0; $i < $max; $i++)
{
    if ($i % 1000 === 0)
        echo $i, '(', number_format(memory_get_usage(),0, '',' '),')', "\n";
        ;
    $obj = new stdClass;
    $obj->name = 'just some data';
    $store[] = $obj;
    unset($obj);
}

So to answer your question: You need to test how much memory your scenario actually consumes, this will show you how many object instances you can have. It's less the arrayaccess but more the actual number of objects instances and the data associated with them in total of your application.

See as well: PHP: do arrays have a maximum size?

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
1

My Question is: Would PHP be able to handle this amount of class instances? I mean this is a lot of classes and I am worried it could easily ruin my memory consumption.

My motto is; if you're asking questions about limits, you're probably doing something wrong. Why do you need 8k instances of a class? Wouldn't a simple array suffice for this specific case? Are you building a list? If so, wouldn't it be beneficial to implement paging?

I use objects when I can and when they're called for. If you're using 8k of objects, you're probably doing something like reporting, where instantiating an object is not really suitable for, and is generally discouraged. If you want to do reporting, either use simple arrays (as you won't actually use the behaviour of the object), or leave the calculations to the database.

Berry Langerak
  • 18,561
  • 4
  • 45
  • 58
  • ActiveRecord within MongoDB is making me consider this. This arrayaccess is used for subdocuments so as to allow a posts model to be assigned within say a "thread" model. – Sammaye Jul 25 '11 at 10:25
0

Question is: Can you use it? It works fine for index arrays

http://sandbox.phpcode.eu/g/38fde.php

this works fine

<?php 
class c1{ 
   function c1(){ 
      echo 'c1'; 
   } 
} 
class c2{ 
   public $username; 
   function c2(){ 
      echo '_c2'; 
   } 
   function getUsername(){ 
       echo $this->username; 
   } 
} 

$c[0] = new c1(); 
$c[1] = new c2(); 
$c[1]->username = "test"; 
$c[1]->getUsername();
genesis
  • 50,477
  • 20
  • 96
  • 125
  • I have unit tested my class and it works awesomely but I am making a mongodb active record which is why I use arrayaccess (subdocuments). So when doing offsetGet() I detect if the arrayaccess class has a $class set (from the parent model), if so populate the current offset with a new class of it and return that offset. So yea it works perfect I am just worried a little about memory :). – Sammaye Jul 25 '11 at 10:15