PHP - comet memory problems - php

This seems to have been discussed quite a bit. I've tried several things I've found, but no luck.
I have a "hacky" cache built that stores objects received from XML calls. The XML calls proved to take too long on page loads, so a user can push a button in the admin to rebuild the cache. The cache routine keeps dying with a memory allocation error.
I know this is a very vague question, but I'm not sure it would help to post a big section of code either.
I am "unsetting" every varaible after I finish using it. I'm calling gc_collect_cycles() which doesn't seem to do anything at all.
I have two anonymous functions that get called over an over....could these be the culprits?
What should I be looking for? Would doing a sleep() help at all?
Code Edit
Here is the code: http://pastebin.com/8M1Dk73E
On line 79 of the pastebin code, I'm calling gc_collect_cycles. Not sure if that is a good place to put it or not.
I am using foreach loops instead of for loops, which I know makes a huge difference with objects being copied, but I would think if I unset the variables it should work the same even if the execution time is longer.
Well, I'm at a loss, so any thoughts would be helpful.

This may be related to gc_collect_cycles. In some php versions and in some loop conditions this function will fail to collect the cycle: For instance, see: https://bugs.php.net/bug.php?id=53803 and https://bugs.php.net/bug.php?id=53071
If you can, try updating PHP to 5.3.9 and see if it works. If not, try dropping the collection and relying exclusively on unset() (keeping in mind that unsetting global variable only destroys it within the function) and you'll need to unset it from the $GLOBALS array if you want to destroy it everywhere.
If you're still stuck, try tracking your memory carefully as it moves through the loop by using memory_get_usage() with a note after anything that should require or release memory. Something like:
try{
$result = $client->GetListingPhotosWithFullPath(array('mlsID'=>$bid->MlsID, 'mlsNumber'=>$bid->MlsNumber));
echo "Got Photos with Full Path on line ".__LINE__." - Now using ".memory_get_usage()."<br />\n";
$listing->photos = $result->GetListingPhotosWithFullPathResult->Photo;
echo "Setting $listing->photos on ".__LINE__." - Now using ".memory_get_usage()."<br />\n";
(isset($opt->comet)) ? $msg("Photos received.") : '';
//Memory Cleanup
unset( $result );
echo "\$result unseet on ".__LINE__." - Now using ".memory_get_usage()."<br />\n";
}
This should let you see where your cycle is building up memory.

Related

Is it bad practice to dynamically change a value with an infinite while loop?

I'd like a section of text that is already dynamically changing every 10 minutes to do it without refreshing the page. I was thinking something along the lines of:
<?php
while (1 < 2) {
echo $value;
sleep(60);
}
?>
I realize that's a dumb way to make a while loop run and I would think it would work with just "while(){}" but I just wanted to make sure, that will be corrected when I actually write this thing as long as this isn't terrible to do. If there is a better way I'd love to hear it! thanks!
Edit: I just noticed it would echo the value after the first, any cleaver ways to make it replace it?
Edit2 Here's the php function I already written to retrieve the changing value:
<?php
function getTotal($basePrice){
$dogeValue = file_get_contents("https://www.dogeapi.com/wow/?a=get_current_price");
$postage = .49/$dogeValue;
return round($sellAmount = $basePrice/$dogeValue - $postage - ($basePrice*0.1/$dogeValue));
}
?>
The short answer: yes, that is bad practice.
Reasons include:
You tie up your server (will probably time out)
Unless you play around with the buffering, things will not be reflected at the time you want
You never send the close tag to the browser (or anything else that happens later).
It is tricky to overwrite what was already there, so you end up with the output increasing instead of changing.
Recommendation:
Use client side code (javascript, AJAX) - don't try to do this server side.
You can see an example of periodic AJAX at https://stackoverflow.com/a/6378771/1967396 .
For periodic JavaScript, see many good answers at Is there any way to call a function periodically in JavaScript?
This script will never show you anything, because until processing the php script is not done, web server doesn't send anything to output, considering your infinite loop, it will never happen.
instead of this not-working idea, use Ajax, cron jobs, or even pure javascript, its very simple and more rational certainly.

Why does var_dump(array) result in a 500 error in Magento?

I'm trying to see what is inside all the objects of the Magento system, but when I try to var_dump the $_links variable (containing all information needed for rendering the links in the header of every page) from inside the top links template, my server responds with a 500 error. Anyone know why?
Dumps of Magento objects get a bit messy, even if there isn't recursion there is all the EAV and cache stuff. When you have an array you'll need to dump them individually:
foreach ($_links as $object) {
var_dump($object->debug());
}
It's likely a memory error. Magento's object can be huge, and the default var_dump implementation in PHP isn't that smart about some of the circular references.
Install xDebug is a must. With xDebug, the var_dump function gets a lot smarter, and the memory limit exhausted errors mostly go away.
Magento is a huge memory hog. Most likely, you're running out of available memory.
Instead of var dumping the object itself, dump the objects data using its ->toArray() method. Note: all Mage_ objects inherit this method.
HTTP 500 errors will occur in scenarios like this when PHP spewed an error, and you did not configure your setup to display it to the user.
Look in your error log (something like /var/lib/httpd/log/error_log) to find out what's actually going on.
Possibilities include:
Syntax error
Headers already sent before output
Memory exhaustion from printing huge variable
In most of cases it's because $_links variable contains a lot of huge nested objects. Try the xDebug extension for PHP - it allows to tune var_dump output to limit nesting level and amount of displaying data.
$_link variable consist huge number of objects inside, we needs to debug to print the object
print_r($_link->debug());
(or)
var_dump($_link->debug());
I solve my var_dump(array) result in a 500 error in Magento2 issue as below(May be someone help)
//app/code/MyCompany/Shipping/view/adminhtml/templates/order/view/items.phtml
foreach ($_items as $_item):
echo "<pre>";
var_dump($_item->debug());
echo "</pre>";
Sample Output:

PHP - debug_backtrace() crashes - what can I do?

I looked at the messages I could find, but didn't find an answer that appears to help. I have a routine that calls debug_backtrace() and then cycles through the elements, outputting them in a nice format for my log. This works fine in most cases.
In some calls, the system just hangs. Assuming the following:
$curStack = debug_backtrace();
foreach ($curStack as $myStackLevel) {
$test = gettype($myStackLevel);
// code to write out contents of $myStackLevel
// Log that we are getting the next item
}
// Log that the foreach is done
In some cases, PHP just dies - I can see the log that it processed the current item, but it crashes on the foreach line (or at least before I can programatically see the contects of the next $myStackLevel.
In one message here, I saw something about recursive calls and using serialize, but I can't use serialize (I use PDO and had the message "You cannot serialize or unserialize PDO instances") So that's out.
The funny thing is that, if it crashes, the PHP error system still provides a complete dump of the stack.... (I found this out when I tried to use serialize).
Any help is appreciated....
Thanks,
JustMeToo
Are you trying to output the contents of the object elements? It's likely that you have a recursive object graph that causes the PHP process to either overflow the stack or take too long to run.

RSS Parser for Twitter is Slow - why?

I am making use of this script to get the first item of my Twitter feed. However, it is slow (it takes 3 to 4 seconds to load page now). Why is it so slow?
Here is how I use it.
require_once 'rss_php.php'; //see link above
$rss = new rss_php;
$rss->load('http://twitter.com/statuses/user_timeline/XXXXXX.rss');
$feed = $rss->getItems(false, 1);
echo $feed[0]['title'];
echo $feed[1]['title'];
I do get this PHP notice:
Notice: Undefined variable: tempNode
in
C:\wamp\www\rss_php.php
on line 137
I don't know why since this works, line 137 is this line:
return $tempNode;
Thanks all for any help. I appreciate any advice on speeding this up.
Fetching content from a remote location can potentially introduce some rather ugly loading issues.
Try saving the contents of the RSS feed in a local file and see if the problem persists when loading from a local drive.
If this fixes the issue, you should look into caching the contents of the feed every once in a while.
Firstly, line 110 of your pastbin is assigning a variable that was never declared. As such, any requests or assignments to an undeclared variable will do this. From what I see it should be as simple as adding $tempNode = Array(); just below the function call of the extractDOM method.
Next, since this is a script from someone else I would recommend asking them what you can do to improve performance. From what is in the pastbin I don't see anything elaborate going on, nor do I see you using the library incorrectly, but ultimately they would know better.
After line 138 in rss_php.php (v.1 Free version) file paste this:
...
if (!isset($tempNode)){
$tempNode = null;
}
return $tempNode;
...
Enjoy
;)
Getting rid of that return $tempNode; notice is easy, but not your problem, it just needs to be defined out of the forloop in that extractDOM function.
Optimizing your php code is a big task. I'm assuming that the api call is the majority of the time, but if you want to try and speed your code up a bit I would look into tutorials on how to do that:
http://ilia.ws/archives/12-PHP-Optimization-Tricks.html
http://progtuts.info/55/php-optimization-tips/
http://hungred.com/useful-information/php-micro-optimization-tips/

PHP equivalent of ASP.NET Application/Cache objects

My Google-fu hasn't revealed what I'm looking for, so I'm putting this one out to the crowd.
Coming from an ASP.NET development background, I'm used to having the Application and Cache collections available for me to stash rarely-modified but often-used resources (such as lookup rows from a database or the contents of static XML documents) in the memory of the web server, so I don't have to reload these often-used items during every request.
Does PHP have an equivalent? I've read up briefly on the memcache extension, but this won't work for me (as I don't have control over the server configuration.) I'm tempted to implement something that would allow me to pre-parse or pre-select the resources and generate a sort of PHP cache "file" that would construct the cached object from literals stored in the file, but this seems like a very hacky solution to me.
Is there something in PHP (or, alternatively, a helper library of some sort) that will allow me to accomplish this using best practices?
In short, no, such a thing is not available natively in PHP. To understand why, you have to understand that PHP has its entire environment built for each request, and it is subsequently torn down at the end of the request. PHP does give you $_SESSION to store per session variables, but after digging into the docs you will see that that variable is built during each request also. PHP (or mod php to be more specific) is fundamentally different from other "application servers". Basically, it is not an application server. It is a per request script runner.
Now, don't get me wrong, PHP lets you do application level data store, but you will have to go to a database, or to disk to get it. Remember this though, don't worry about optimizing for performance until it is shown that preformance is a problem. And I will guess that 99 times out of 100, by the time performance is an issue that isn't due to some poor code you wrote, you will have the resources to build your own pretty little memcached server.
Take a look at Zend_Cache library, for example. It can cache in multiple backends.
This is a bit of a hack but but works in php 7+
Basically you cache your data to a temp file and then use include to read the file, which is cached in memory by the php engine’s in-memory file caching (opcache)
function cache_set($key, $val) {
$val = var_export($val, true);
// HHVM fails at __set_state, so just use object cast for now
$val = str_replace('stdClass::__set_state', '(object)', $val);
// Write to temp file first to ensure atomicity
$tmp = "/tmp/$key." . uniqid('', true) . '.tmp';
file_put_contents($tmp, '<?php $val = ' . $val . ';', LOCK_EX);
rename($tmp, "/tmp/$key");
}
And here’s how we “get” a value from the cache:
function cache_get($key) {
#include "/tmp/$key";
return isset($val) ? $val : false;
}
from https://medium.com/#dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad

Categories