UPDATE 4/3/2012:
A commenter pointed out that str_replace wasn’t properly limiting replacements via the count param. After looking around it seems that $count no longer limits replacements (I’m honestly wondering if it ever did…) and rather returns a number of replacements performed. For any users experiencing this I’d recommend using preg_replace as it effectively supports limiting replacements.
preg_replace('/findit/i','replaceit',$haystack,1);
I could have sworn this func worked using the $count as a limit in the past…
If you’re using a simple str_replace() call in PHP and getting a strange Fatal error that doesn’t make a whole lot of sense to you I have a hunch as to why.
Fatal example:
$file_name = str_replace('findit', 'replaceit', $haystack, 1);
In PHP 5.0.5 some changes were made to how PHP handles variables, functions, and references. This broke a lot of older code but also introduced some vague and questionable fatal errors. They meant well by doing this by essentially requiring parameters be passed via reference. I’m assuming this was to prevent PHP from copying large pieces of data to work on them and thus helping memory performance overall. Luckily there is a simple fix, just declare your variable to be passed inline.
Working example:
$file_name = str_replace('findit', 'replaceit', $haystack, $count = 1);
Note: if you’re working with a large data set in a loop I would highly recommend setting the reference outside of the loop and avoid this inline method.
Client side cache is both a friend and an enemy. As many web designers and developers have learned in the past what it saves you in bandwidth is worth more than it’s share of headaches. With that said one of it’s major headaches is old files on end users computers being used and breaking functionality. This can be felt in layout as well as code (e.g. undefined function ‘do_important_stuff()’) if you’re newly modified files never make it to your end users.
There is an old trick that’s been around for a good while and helped this a bit, an old annoying and version tracking pain in the ass trick. You would change your file names with each major revision (core.v1.js or member.v1.css) which would cause browsers on the client side to request and store the file thinking it was new. From a design aspect it wasn’t to bad, from the version control aspect it wasn’t to bad, and from the implementation aspect it wasn’t to bad… but it was annoying.
Trying to move away from this you’d more than likely discover the GET variable hack. Basically appending useless garble to the end of your file name (file.css?garble=1351341) would ensure your end users browser fetch the file from your server. This was usually done with a variable in your source or more often than not a Unix time stamp. A concern with this method arose in your bandwidth bill if you did it wrong. Most people would just append the time stamp, and since it changes everyone second every single page load would cause yet another extra and pointless call to the server for the same old unmodified file. As if that wasn’t already fugly and possibly expensive (depending on your traffic) it didn’t work in some versions of IE.
During a discussion on better ways to handle JavaScript cache busting with our head software engineer I came up with a fairly simple idea that I hadn’t thought of before… let the file bust it’s own damn cache! Basically using PHP and file system mtimes we should be able to not only make this problem null and void but we can fix it once and never look back.
Using a couple quick functions in PHP and a simple rewrite rule placed on the server we were up and running in no time. Some code snippets and explanations will follow.
PHP include function:
function javascript_include($file_name = null){
if (empty($file_name)){
return false;
}
$file = WWW_WEB_DIR.'/js/'.$file_name;
$timestamp = 0;
if ($file_exists($file)) {
$timestamp = filemtime($file);
} else {
return false;
}
$script_url = "/js/$timestamp/$file_name";
return "<script type=\"text/javascript\" src=\"$script_url\"></script>\n”;
}
Using PHP function:
<?=javascript_include('site_core.js')?>
Resulting output:
<script type="text/javascript" src="/js/135134134/site_core.js"></script>
Rewrite rule:
RewriteRule (.*)/[0-9]+/(.*\.js)$ $1/$2 [PT]
Summary:
So there you have it, completely automated and effective cache busting. This works because browsers universally see the change in the directory structure and automatically assume it’s a new file causing an initial fetch of the file and caching it. If you publish changes to that file the mtime on the file system of the server will be updated, therefore the next request to include said file will have a different directory structure.
Hope this helps others dealing with caching headaches.
Working in Flex and/or Flash you often run into the same problem many times and forget the easy and common sense answer. Security sandbox violations for me is one of those cases.
Googling for answers is usually fruitless and starts talking about server side crossdomain.xml policy files and meta data. These are important in the long run but what about when they’re in place and you’re just testing new client side code. Well I’ve done this a few times now and EVERY time I do it I completely forget the quick and easy work around. So if you’ve looked into the crossdomain.xml tutorials and everything is ship shape but you still can’t test from your local machine I suggest doing the following.
1. right click on any .swf file
2. choose “Settings…”
3. Privacy Tab
4. “Advanced…” button
this will load up an Adobe page that allows you to change and tweak global settings in Flash player that can only be done so there. It’s pretty clutch.
5. click “Global Security Settings Panel” on the left side menu
6. click “Edit Locations…”
7. click “Add Locations…”
8. in the prompt window that comes up put /
9. click confirm
10. change radio button to “Always allow”
Wahlah… your local .swf files are now null and void as far as cross domain sandbox rules are concerned in the world of Flash player.
What you’ve essentially done here is tell Flash Player to ignore security rules for any files in your root files system. If you’re security minded and run a lot of .swf files that you don’t trust locally I wouldn’t recommend this setting as it completely overrides security measures put in place to protect you. You can also use the “browse” functionality to pick specific files which realistically is much safer from a security stand point. I myself don’t worry about it because I don’t store any .swf files locally when it boils down to it.
my new baby. (Cannondale CAAD9 6)
I currently have an Asus Eee PC (1002ha) and to say the least am not an avid Windows fan. Since the day I unpackaged this puppy I have been on a quest to find the best OS I could for the lil guy. So far I’ve ran EasyPeasy and OS X (needs drivers sadly otherwise this would have never been written) and looked into running Moblin (although I must admit I never installed it). Long story short EasyPeasy was my distro of choice.
Recently 9.04 went stable and I had heard good things but after looking over the EasyPeasy forums decided not to upgrade. Apparently it was breaking a lot of stuff and 8.10 was running solid enough to keep me content.
Over memorial day weekend I upgraded my desktop (8.10) to 9.04 and bricked the box so I ventured over the Ubuntu.com to get a fresh 9.04 install disk. After doing a clean install the system was unstable and Firefox was a mess. So I decided to check out Ubuntu.com again to see if any others were reporting issues or if I just had a botched install. That’s when I noticed it… 9.04 Netbook Remix Edition! I’m not sure how I missed this memo but seriously wtf!? After looking over the wiki and confirming that the 1000h models were running fairly solid I was sold.
I downloaded their .img file threw it on my thumb drive using my Windows machine (9.04 wasn’t working yet) and plugged that puppy in. The install was painless and fast and I was up and running in no time. On the Ubuntu forums I had seen some issues of people reporting failures coming out of “sleep mode/stand by” and another user mentioned on their non-netbook that enabling “Effects” (and inturn upping the vid drivers) fixed the problem. Now this is what shocked me… even on my 1002ha I was able to enable “Extra” (wobbly windowns, drop shadows, fading menus… the whole 9 baby!) under the effects panel (System->Preferences->Appearance->Visual Effects) and not only did it work… it worked well… damn well.
I had never expected the Compiz stuff to be so snappy on such low end video hardware (Intel Integrated 1.6Ghz Atom & 2 gigs of RAM) but it is! One of my biggest pet peeves with my old EasyPeasy install were the hoops you’d have to jump through to disable “Tap to Click”. I’d read over tutorials… borked some xorg configs and still because of the “special” touchpad they used on the 1002ha (multitouch … some random vendor) I wasn’t able to get it to work properly. With 9.04 Netbook Edition it was as simple as unchecking a box in mouse preferences!
If you’re running EasyPeasy (love you guys, but sorry) I HIGHLY RECOMMEND you go ahead and grab the new official Ubuntu netbook build (link at the end of the article) and get it on your Eee PC A.S.A.P. I’m one very happy camper now that my lil guy has all the bells and whistles. From my testing so far multitouch works, web cam works, sound works, function keys (brighness, volume, etc) all work (the mute button didn’t work under EasyPeasy)!
Now these next parts are mere speculation (as when you’re happy with a piece of software you tend to be a touch biased) and I haven’t tested these claims thoroughly but the machine feels faster, battery life seems to have improved, Flash (a known resource hog on all Linux boxes) seems to even perform better (sudo apt-get install flashplugin-nonfree).
Hope this helps push a couple of other curious netbook owners over the edge and helps them take the plunge!
Ubuntu Netbook Edition : http://www.ubuntu.com/getubuntu/download-netbook
We launched our Video Chat Application to mostly good reviews from the user community. One of our biggest complaints/bugs was “The app doesn’t load… it just displays a blank white page after the “loading” screen goes away”. We’d tried old Flash player versions, older browsers, multiple OS’s and STILL couldn’t reliably duplicate the error. After a couple weeks of the app being live someone started a thread on the community forums titled “Think I know why people are having problems getting into chat..”. Sure enough the user pointed out a development over sight. It seems that if a user has set their “Local Storage” settings in Flash to 0 the app would fail to load, the forum thread gave a quick description on how to set this to a higher number.
We weren’t exactly sure as to why this happened on some systems nor why your average user would have changed this (testing locally wouldn’t duplicate the bug, but the fix was indeed working for people left and right). So we let people in customer service know about this fix… but that still didn’t answer why it was breaking. We knew it had to do with local storage (obviously) and more than likely it was related to saving Local Shared Objects to the clients system to keep their settings preferences between app sessions. What I found out just really pissed me off more than anything.
So turns out if you’re using Local Shared Objects and a user has disabled local storage your app will run fine. You can freely write and read to the Shared Object without any issues the problem arose when you’d issues a SharedObject.flush(). But that wouldn’t fail UNLESS a user has checked “never ask again”. See if a user had set the number to 0 when you issued a flush() the app would ask them for permission but if they had checked “never ask again” the SharedObject would throw a fatal error (that doesn’t even register in the Debug Flash Player mind you).
In short… if using Local Shared Objects in your app your code should look something like this.
public var my_so:SharedObject = SharedObject.getLocal('your_so');
public function save_so():Boolean
{
var so_status:String;
try
{
so_status = my_so.flush();
}
catch(e)
{
Alert.show("you'll need to enable local storage to save settings.");
return false;
}
if(so_status == "pending")
{
// set to 0 ... prompted user for allow or deny... might have saved it.
return false;
}
else if(so_status == "flushed")
{
// successfully wrote SO to disk.
}
return true;
}
nerd.com … office sport vanguards.
oh Google News how I love your sense of humor.
In Flex recently I was trying to use the dataProvider of a List component in another component. It was for a Video Chat Application and it would make whispering another user easier by facilitating auto-completion on a name. Long story short the dataProvider for said list had various sorts and filters applied to it so saying list.dataProvider wasn’t an option because we needed to see the entire list not just a filtered subset.
ANNNNYWAY… I needed to duplicate and keep a copy for comparisions and such in the other component. After looking around and getting very frustrated I started messing around with a mish-mash of semi-complete ideas gathered from various sites. This was my solution and I hope it helps someone out there.
function copy_ac(in_array:ArrayCollection):ArrayCollection
{
return new ArrayCollection( in_array.source.concat() );
}
I'm guessing this took more than one try.
[video]
nice work /b/tards… you make me proud :)
a gift from the guys at work.
fun when you're bored and feeling musical
yep… I bought it.