<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code Fury &#187; Kenny Katzgrau</title>
	<atom:link href="http://codefury.net/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://codefury.net</link>
	<description>One programmer's formatted output stream</description>
	<lastBuildDate>Tue, 22 Jun 2010 23:36:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ajax-proxy: A PHP AJAX Proxy with Cookie Support</title>
		<link>http://codefury.net/2010/06/ajax-proxy-a-php-ajax-proxy-with-cookie-support/</link>
		<comments>http://codefury.net/2010/06/ajax-proxy-a-php-ajax-proxy-with-cookie-support/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 23:36:44 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=234</guid>
		<description><![CDATA[A common annoyance in the world of AJAX is the ol&#8217; cross-domain request error. That is, a script sitting on domain1.example.com can&#8217;t make AJAX calls to domain2.example.com. This is in place for the sake of security, but sometimes developers have legitimate reasons to do so.
A common workaround is writing a server-side script that will sit [...]]]></description>
			<content:encoded><![CDATA[<p>A common annoyance in the world of AJAX is the ol&#8217; cross-domain request error. That is, a script sitting on domain1.example.com can&#8217;t make AJAX calls to domain2.example.com. This is in place for the sake of security, but sometimes developers have legitimate reasons to do so.</p>
<p>A common workaround is writing a server-side script that will sit on domain1.example.com, and make proxy requests to domain2.example.com, and send the output back to the client. Many times, this is a &#8220;quick and dirty&#8221; solution to a common problem. You can find many of these <a href="http://www.google.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=php+ajax+proxy">short &#8216;n ugly procedural proxy scripts online</a>.</p>
<p>But what if our needs are more complicated? What if our AJAX calls needed to be made over an authenticated session which requires forwarding of cookies? This is much harder to find online, and is a bit more complicated.</p>
<p>Lastly, just try and find an AJAX proxy that doesn&#8217;t rely entirely on cURL as it&#8217;s request mechanism. Developers using shared hosting or servers with draconian admins might not of the luxury of access to third-party fluff like cURL.</p>
<p>Over the past few weeks, I&#8217;ve developed <a href="http://github.com/hugeinc/ajax-proxy">ajax-proxy</a> over at <a href="http://hugeinc.com">HUGE in Brooklyn</a>, which is a class and script that solves both of the problems above. Additionally, it&#8217;s functionality is entirely encapsulated inside of a re-usable class. It was made so that it could stand alone on a server as proxy.php, or be incorporated into a larger framework like Zend, Kohana, or CodeIgniter.</p>
<p>Here are it&#8217;s features:</p>
<ul>
<li>Uses cURL, but falls back to the less-speedy fopen if the former sin&#8217;t available</li>
<li>Forwards cookies and other headers in both directions</li>
<li>Has optional error and exception handling for behavior as a standalone script (frameworks would likely not want this)</li>
<li>Extremely well documented (I&#8217;m a documentation fanatic)</li>
<li>Written entirely in OO PHP 5, to the Zend standards</li>
</ul>
<p>Additionally, the proxy underwent 2 weeks of development and intensive code review by the HUGE development team before it&#8217;s v1.0 push to GitHub. This is by no means a &#8220;quick and dirty&#8221; solution — it&#8217;s a rock-solid, full featured ajax-proxy that&#8217;s dead easy to use. Assuming proxy requests were going to be made to a base url of domain2.example.com, the code to run the proxy looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$proxy</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AjaxProxy<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'domain2.example.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$proxy</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>execute<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If there&#8217;s anyone that loves simplicity, it&#8217;s me. Of course, there are more constructor options, but that&#8217;s better left to the README.</p>
<p>Anyway, the project is posted on GitHub at: <a href="http://github.com/hugeinc/ajax-proxy">http://github.com/hugeinc/ajax-proxy</a>, where there is also pretty extensive documentation on the class&#8217; usage. For documentation about the internal class members and methods, everything is doc&#8217;d with PHPDoc.</p>
<p>As a side note, I think it&#8217;s about time that I add KLogger to github. I get a fair amount of emails from people telling me they&#8217;re using it, and it&#8217;s about time I incorporated some new features in, like rolling log files, etc. I&#8217;m tired of having dusty old zip files sitting around. I&#8217;ll make another post when I put it up there!</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/06/ajax-proxy-a-php-ajax-proxy-with-cookie-support/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Get A Job As A Programmer</title>
		<link>http://codefury.net/2010/06/how-to-get-a-job-as-a-programmer/</link>
		<comments>http://codefury.net/2010/06/how-to-get-a-job-as-a-programmer/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 20:24:21 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Jobs]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Offtopic]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=227</guid>
		<description><![CDATA[It seems that for the better part of my life, America&#8217;s economy has been in murky water. I was born into a Reagan economy (good), graduated to Bush Sr. (bad), did my time with Clinton (good), and started looking for jobs as a developer during Bush Jr.&#8217;s tenure (bad). And while I&#8217;ll abstain from the [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that for the better part of my life, America&#8217;s economy has been in murky water. I was born into a Reagan economy (good), graduated to Bush Sr. (bad), did my time with Clinton (good), and started looking for jobs as a developer during Bush Jr.&#8217;s tenure (bad). And while I&#8217;ll abstain from the more political conversation, Obama&#8217;s reign doesn&#8217;t look much better in terms of economic health (of course, he inherited a lot of trouble).</p>
<p>And throughout those recessions of the last ten years, there doesn&#8217;t seem to be a much more exciting topic for news anchors to talk about then joblessness. <em>The unemployment rate is up, it&#8217;s down, this year&#8217;s graduates can&#8217;t find jobs, and here&#8217;s the story of Marty McNoJob, who has been unemployed for 62 years</em>. Many people (grandmas in particular) eat it right up, and try and convince you to get into whatever field is <em>hot</em> at the time.</p>
<p>And accordingly, mountains of advice articles (like this one) try and give you a good idea of how to get a job in this tough economy. <em>Put these words on your resume, wear a suit, get a minor in management, send thank-you notes, get a degree if you don&#8217;t have one, and talk about how much you raised revenue at your last job, etc.</em></p>
<p>But here&#8217;s the startling truth about one-size-fits-all advice like this (<a href="http://www.google.com/search?hl=en&amp;safe=off&amp;q=job+search+tips&amp;aq=f&amp;aqi=g10&amp;aql=&amp;oq=&amp;gs_rfai=">which you can find almost anywhere</a>): These rules do not really apply to software development. Software development is a completely different ball game.</p>
<p>So now that I&#8217;ve given you a fairly lengthy segway into the actual topic of this post, let me be clear about my background:</p>
<ul>
<li>As a freelancer, I&#8217;ve been to a hell of a lot of interviews</li>
<li>Almost all of those interviews resulted in job offers (yes, in this economy)</li>
<li>I&#8217;ve interviewed plenty of people for employers and as a business owner</li>
<li>I&#8217;ve written plenty of resumes for co-workers and friends that have gotten them interviews</li>
</ul>
<p><strong>The number one rule to getting a job as a programmer is to be good at what you do. This applies to recent graduates too. </strong></p>
<p>When you go to school for a computer science degree, there&#8217;s a good chance you went somewhere that offered other engineering degrees such as Mechanical, Civil, and Electrical Engineering. Think of those other majors. How the hell is a Civil Engineering major going to get any real field experience before his first job? He can&#8217;t. But programmers have it completely different. Programmers can get field experience as early as they want. If a young programmer in middle school wants to write a website or a video game, he can learn how. He can read up on the vast, free resources on the internet and build up his awesomeness. If a Civil Engineering major wants to build a bridge in high school, he better like playing with Legos.</p>
<p>The programmers who get jobs in a tough economy are those with experience and projects they can associate their names with. That leads me to my next rule.</p>
<p><strong>The second rule to getting a job as a programmer is to have a portfolio.</strong></p>
<p>Software development is a wacky world in that good companies hire people based on talent, not on &#8220;years of experience&#8221;. In fact, 15 years&#8217; experience in the world of software development could mean absolutely nothing. This is something that recruiting firms have yet to grasp (which is why programmers should probably stay away from headhunting firms, which is for another post). Good hiring managers know this.</p>
<p>So you may be thinking, &#8220;I&#8217;m a recent grad, how can I possibly have a portfolio this early?&#8221; If you became a software developer because it supposedly paid well, you&#8217;re out of luck. You likely don&#8217;t love the craft, and you might lack the ambition to have done anything significant as a developer up until this point. But developers who love what they do can:</p>
<ul>
<li>Get an internship</li>
<li>Get involved in an open-source project</li>
<li>Roll your own project</li>
</ul>
<p>The point is to have something cool to talk about at your interview. If you&#8217;re being hired out of college, for the love of god, make sure that you have something that your interviewer can talk about other than what your favorite classes were in school.</p>
<p><strong>The third rule is that you can&#8217;t look like a rookie.</strong></p>
<p>Forgive the l33t talk, but in a tough economy, companies don&#8217;t have the money to risk on hiring a noob. They want to hire someone who can jump in on a project and hit the ground running. There is little to no &#8220;on the job training&#8221; in the world of software development.</p>
<p>So what can you do to avoid looking like a noob?</p>
<ul>
<li>Chances are, you shouldn&#8217;t wear a business suit to the interview. The goal is to look well put-together, but fairly casual.</li>
<li>Bring a nice stack of screenshots which showcase projects you worked on. Don&#8217;t unnaturally force the interviewer to take a gander, but if you&#8217;re explaining a project you worked on, it can be much more effective to put an image to the description.</li>
<li>Don&#8217;t use idiotic jargon on your resume. Example resumes online have absurd phrases like &#8220;goal-oriented, motivated individual seeking position in a fast-paced agile environment where they can grow, learn, and advance&#8221;. All I see when I read that is &#8220;n00b, noob, noob, I&#8217;m a fat scrub.&#8221;</li>
<li>Don&#8217;t use acronyms that you can&#8217;t back up. If you list both Ruby and PHP as languages that you know, be sure that you can answer thorough question on each. And expect to answer the fraud destroyer questions like, &#8220;So can you tell me about some of the ways that PHP and Ruby differ for both good and bad?&#8221; This is truly an open-ended question, and the interviewer is really just trying to gauge your expertise.</li>
</ul>
<p><strong>The fourth rule is that it&#8217;s okay to say that you don&#8217;t know.</strong></p>
<p>&#8220;I don&#8217;t know.&#8221; &#8212; A wonderful phrase used by millions of students in the world to get teachers off their backs when they&#8217;re called out because they weren&#8217;t paying attention. But in the business world, apparently &#8221;I don&#8217;t know&#8221; is <a href="http://www.forbes.com/2010/04/26/words-work-communication-forbes-woman-leadership-career.html">an invitation to disaster</a>.</p>
<p>Guess what? If you&#8217;re pitched a cut-and-dry question like &#8220;How is garbage collection handled in C#?,&#8221; and you don&#8217;t know, just say so! Essentially, be calm and say something like &#8220;that&#8217;s something I&#8217;ve actually never looked very deeply into, so I&#8217;m not entirely sure.&#8221; The interviewer may ask you describe how you <em>think</em> it works. This is when it&#8217;s okay to say something that might be wrong.. He just wants to hear you think out loud.</p>
<p>The worst thing you can possibly do is act like you <em>do</em> know, but be wrong. In software development, admitting when you need help or you don&#8217;t know how to do something is key to the success of the team. Project managers want someone with a &#8220;can do&#8221; attitude, but they don&#8217;t want someone who is going to throw the project off schedule because of his pride and his refusal to admit he needs help.</p>
<p>Also, saying you <em>don&#8217;t know</em> does not make you look like a rookie (see rule #3). Software development is a gigantic, always-changing field, and it&#8217;s impossible to know the ins-and-outs of everything.</p>
<p><strong>The fifth major rule is that you have to build street cred.</strong></p>
<p>Expect to be Googled (especially if you have a unique last name like <em>Katzgrau</em>). For me, no one&#8217;s name is safe from The Google. Whenever I&#8217;m about to work with another developer, I check up on their internet rep. Why?</p>
<p>Because if they have a website, blog, github account, stackoverflow account, sourceforge page, etc, I can begin to verify their authenticity. Suppose I get two resumes, and one of them has a GitHub account listed. If I can see some of their code contributions online, I have a much more realistic sense of who they are as a developer &#8212; not the actor that walks in the door trying to impress me. I would absolutely feel much better working with someone who&#8217;s code quality and contributions I can verify.</p>
<p>Get a website, blog, or some other public account where the smart guy that you are can really shine.</p>
<p><strong>A word on having a college degree:</strong></p>
<p>College degrees are not always required for some of the best development jobs. You can easily make 100k+ if you&#8217;re great at what you do, and you don&#8217;t have a degree.</p>
<p>That being said, you should probably have one. I hate to think it, but some companies and hiring managers will actually check to make sure you have a degree despite other fantastic credentials on your resume. It&#8217;s practically a stamp of approval from another institution.</p>
<p>But in reality, what good is a degree? There are certainly some institutions out there whose Computer Science degree courses are fantastic, useful, and progressive. But the majority of them &#8212; and I think I&#8217;m safe to say this &#8212; suck. Students are usually stuck in a classroom with professors who haven&#8217;t worked in industry for at least 20 years, if ever. They can&#8217;t tell you about things like unit testing, design patterns, version control, agile development, code reviews, or other industry shenanigans like that. But that&#8217;s just my take, and certainly doesn&#8217;t apply to everybody.</p>
<p>It&#8217;s really interesting, because the development fields&#8217; laxness in regard to degrees is in stark contrast to fields like Education. For many teaching jobs, you must have a Master&#8217;s degree. Did that Master&#8217;s really help any teachers teach more effectively? I don&#8217;t know the answer to this question, but I&#8217;m skeptical.</p>
<p>And a degree from a fancy-pants place like MIT will probably help you get in the door (if not from sheer prestige, than probably from networking), but it won&#8217;t carry you forever. Ultimately, it&#8217;s the work that you&#8217;ve done that gets you future jobs, and help you take over the world.</p>
<p><strong>Lastly, some smaller, but important notes that don&#8217;t deserve a spiel</strong></p>
<ul>
<li>Don&#8217;t pitch yourself as a language-specific developer. It&#8217;s important to list technologies that you&#8217;re really good at, but don&#8217;t make it seem like the only thing you&#8217;re interested in is one language. Java developers seem to do this a lot, but I have little basis for this other than observation.</li>
<li>If you&#8217;re still in school, maintain a good GPA, and above all, read this classic on the <a href="http://www.joelonsoftware.com/articles/CollegeAdvice.html">Joel On Software Blog</a></li>
<li>Know at least one language that is widespread. It&#8217;s cool to be a Python developer right now, but most job postings are looking for C, PHP, .NET, or Ruby devs. Python is something that is totally awesome, but it might not open all the doors that you&#8217;d like.</li>
<li>Always make sure your resume is up to date. When you work with a new language or you are on a new project, make sure it gets a spot.</li>
<li>Resumes, contrary to popular belief, do not have to fit on one page. If you&#8217;re a developer with a few or more projects, this can be somewhat difficult to achieve without sacrificing important information</li>
<li>Prepare for the interview. Look up questions commonly asked on the interview on places like <a href="http://glassdoor.com">GlassDoor.com</a></li>
</ul>
<p>Anyway, if you needed this advice, take it to heart, and build your cred. If you read it just to see what I had to say, pick out anything you agree or disagree with and comment. And if you think this is oh-so-absurd, start a flame war.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/06/how-to-get-a-job-as-a-programmer/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>USTORE.js: Cross-Browser Local and Session Storage Made Easy</title>
		<link>http://codefury.net/2010/06/ustore-js-cross-browser-local-and-session-storage-made-easy/</link>
		<comments>http://codefury.net/2010/06/ustore-js-cross-browser-local-and-session-storage-made-easy/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 23:41:45 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=222</guid>
		<description><![CDATA[I tend to get so wrapped up in the server-side portion of web applications, I probably don&#8217;t keep tabs on front-end tips and tricks as well I should. Luckily I work with some of the best client-side developers I&#8217;ve ever met over at HUGE, and I generally get exposed to new front-end marvels whether I [...]]]></description>
			<content:encoded><![CDATA[<p>I tend to get so wrapped up in the server-side portion of web applications, I probably don&#8217;t keep tabs on front-end tips and tricks as well I should. Luckily I work with some of the best client-side developers I&#8217;ve ever met over at <a href="http://hugeinc.com">HUGE</a>, and I generally get exposed to new front-end marvels whether I like it or not.</p>
<p>HUGE is firm that specializes in building sustainable web applications &#8212; they&#8217;re known for their design team, user experience, and revenue generating ability. Their talent is behind the Reuters iPad App, CNN, iVillage, and a<a href="http://hugeinc.com/casestudies/"> host of other clients</a>.</p>
<p>But HUGE also keeps a team of the best developers you&#8217;ll find in NY. And lately, they&#8217;ve begun to contribute to the open source world via their <a href="http://hugeinc.com">GitHub account</a>. Their first release has been something particularly exciting for front-end developers: A cross-browser library for leveraging the local storage capabilities of HTML 5.</p>
<p>Local storage is essentially a mechanism that allows client-side applications to store data &#8212; &#8220;<a href="http://dev.w3.org/html5/webstorage/#disk-space">a mostly arbitrary limit of 5 megabytes</a>&#8221; &#8212; locally. This works much like a cookie, without the absurd storage restriction of 4 kilobytes.</p>
<p>The library was developed by HUGE developer <a href="http://sankhomallik.com/">Sankho Mallik</a>, and he wrote a bit more detail about the library over at his blog. His library, in addition to facilitating cross-browser local storage, also facilitates the use of session storage across browsers (even IE 6, incredibly). That&#8217;s something you can&#8217;t find in other plugins on the &#8216;net.</p>
<p>The project page is at <a href="http://github.com/hugeinc/USTORE.js">GitHub</a>, but I&#8217;d recommend reading up at <a href="http://blog.sankhomallik.com/2010/06/16/ustore-js-cross-browser-local-and-session-storage/">Sankho&#8217;s blog</a> too.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/06/ustore-js-cross-browser-local-and-session-storage-made-easy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Get Your NYC Teacher Certification Fingerprints For Your TEACH Account</title>
		<link>http://codefury.net/2010/04/how-to-get-your-nyc-teacher-certification-fingerprints-for-your-teach-account/</link>
		<comments>http://codefury.net/2010/04/how-to-get-your-nyc-teacher-certification-fingerprints-for-your-teach-account/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 12:59:06 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=216</guid>
		<description><![CDATA[
This post is somewhat of a sequel to my previous post, How To Get Livescan Fingerprints in NYC. Since that entry was oriented specifically towards getting Livescan fingerprints, I wanted to cover the larger issue at hand: The reason so many people are in this dilemma, and how to get out of it.
Read this article if:

You [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>This post is somewhat of a sequel to my previous post, <a href="http://codefury.net/2010/03/how-to-get-livescan-fingerprints-in-nyc/">How To Get Livescan Fingerprints in NYC</a>. Since that entry was oriented specifically towards getting Livescan fingerprints, I wanted to cover the larger issue at hand: The reason so many people are in this dilemma, and how to get out of it.</p>
<p>Read this article if:</p>
<ul>
<li>You are applying for certification through New York State&#8217;s TEACH System</li>
<li>You have paid for &#8216;Fingerprint Processing&#8217; but you have no idea where to get your fingerprints done</li>
</ul>
<p>So at this point, you have probably paid $96+ dollars for &#8216;Fingerprint Processing&#8217; through the NYSED TEACH system, but now they&#8217;ve left you high and dry by leaving vague instructions on how to get your fingerprints done. They mentioned that you can get Livescan prints, a seemingly speedy alternative to the traditional option, ink fingerprints.</p>
<p>Like me, you set out to find an &#8216;Approved LiveScan Service&#8217;, but had no luck.</p>
<p>You can get Livescan prints in two places: The NYPD headquarters in lower Manhattan and the New York Department of Education in Brooklyn.</p>
<p>So where should you go? It depends! Here&#8217;s the dirty truth of application process that they aren&#8217;t very clear in telling you:You cannot get your Livescan fingerprints processed unless you have a referral letter from a school or school official.</p>
<p>So in my girlfriend&#8217;s case &#8212; she was applying for certification, and didn&#8217;t have and schools she was applying to yet. How would she get a referral letter?! What we found out is that she isn&#8217;t eligible without that letter (or at least that&#8217;s what everyone at the NYDOE told us!).</p>
<p>So, if you are in this situation, you have to do everything the hard way. Just get traditional fingerprints at the New York Department of Education at <a href="http://maps.google.com/maps?hl=en&amp;q=65+court+street,+brooklyn,+ny&amp;um=1&amp;ie=UTF-8&amp;hq=&amp;hnear=65+Court+St,+Brooklyn,+NY+11201&amp;gl=us&amp;ei=pF3IS6b0MZS09QSu_-zhCg&amp;sa=X&amp;oi=geocode_result&amp;ct=title&amp;resnum=1&amp;ved=0CAcQ8gEwAA">65 Court Street in Brooklyn</a>. It&#8217;s right by a number of subway lines, including the A,C,2,3,4,5 and a couple others. I think the actual name of the stop on the A/C line is &#8216;Borough Hall&#8217;. Get off, walk a few hundred feet down Court Street, and you&#8217;ll see the building on your left.</p>
<p>You will need a $10 money order to get your prints processed. And even if they tell you they&#8217;ll take a check, they won&#8217;t. Try to get there early, because if you do, there might not be a line.</p>
<p>When you walk into the building, you&#8217;ll have to have your ID checked by the guards. The room you need to enter is immediately to the left of the front entrance. It looks like this:</p>
<p><a href="http://codefury.net/wp-content/uploads/2010/04/doe.jpg"><img title="doe" src="http://codefury.net/wp-content/uploads/2010/04/doe-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Talk to the nice ladies at the desk, and explain that you need your fingerprints done for your certification. They&#8217;ll give you some paperwork, and a pen.</p>
<p>When you&#8217;re all finished, they&#8217;ll send you to the fingerprint room where someone will take your ink fingerprints. They&#8217;ll then sign off on a few things, and give you some papers back. Make a copy of everything, including your receipt, at the copier in the same room.</p>
<p>Finally, you can continue with the certification process. Mail in those cards, along with any yet-to-be processed transcripts, out of state certifications, etc.</p>
<p>When all that&#8217;s sent in and processed by the state (which they say can take a couple months), you&#8217;ll be all set. Everything will eventually be hooked up with your TEACH account.</p>
<p>With all the trouble one has to go through, it&#8217;s really a wonder that NYC has any teachers at all. Am I right or what?</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/04/how-to-get-your-nyc-teacher-certification-fingerprints-for-your-teach-account/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Get Livescan Fingerprints In NYC</title>
		<link>http://codefury.net/2010/03/how-to-get-livescan-fingerprints-in-nyc/</link>
		<comments>http://codefury.net/2010/03/how-to-get-livescan-fingerprints-in-nyc/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 13:58:35 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[certification]]></category>
		<category><![CDATA[city]]></category>
		<category><![CDATA[finger]]></category>
		<category><![CDATA[fingerprints]]></category>
		<category><![CDATA[live]]></category>
		<category><![CDATA[livescan]]></category>
		<category><![CDATA[new]]></category>
		<category><![CDATA[nyc]]></category>
		<category><![CDATA[prints]]></category>
		<category><![CDATA[scan]]></category>
		<category><![CDATA[teach]]></category>
		<category><![CDATA[teacher]]></category>
		<category><![CDATA[york]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=208</guid>
		<description><![CDATA[It&#8217;s obvious that this is a tech blog, and this isn&#8217;t a tech-oriented post. But I know there are a lot of people who are in the same situation as I was yesterday.
Update: How To Get Your NYC Teacher Certification Fingerprints For Your TEACH Account
My girlfriend needed to get her fingerprints taken so she could [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s obvious that this is a tech blog, and this isn&#8217;t a tech-oriented post. But I know there are a lot of people who are in the same situation as I was yesterday.</p>
<p><strong>Update:</strong> <a href="http://codefury.net/2010/04/how-to-get-your-nyc-teacher-certification-fingerprints-for-your-teach-account/">How To Get Your NYC Teacher Certification Fingerprints For Your TEACH Account</a></p>
<p>My girlfriend needed to get her fingerprints taken so she could apply for teacher certification in NYC&#8217;s schools. The NY Department of Education does a pretty stellar job when it comes to clarity in terms of telling teaching prospects exactly what they need to do in order to become certified. One of those things is getting fingerprinted.</p>
<p>They don&#8217;t exactly tell you <em>where</em> to get fingerprinted, although. They mention that they accept traditional fingerprint cards, and the new digital livescan method, but not any names of places that do these things.</p>
<p>A quick search online for &#8220;livescan fingerprint nyc&#8221; yields mostly useless links, with the exception of one company at 130 Williams in lower Manhattan. After a short call, we decided not to go with them due to some questionable fees and their particularly shady website.</p>
<p>So do you want to know where we ended up? The NYC Police Station, at 1 Police Plaza. They do fingerprints from 9am to ~4pm, have a light fee, and they do traditional <em>and</em> livescan fingerprints. It took us the better part of a day to figure out we should go there.</p>
<p>They&#8217;re on the lower east side of Manhattan, a few blocks from the Brooklyn Bridge.</p>
<p>I hope this helps someone who is in a similar situation. Leave a comment if it did!</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/03/how-to-get-livescan-fingerprints-in-nyc/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>My Honest Consumer Opinion of the iPad: Who Cares?</title>
		<link>http://codefury.net/2010/01/my-honest-consumer-opinion-of-the-ipad-who-cares/</link>
		<comments>http://codefury.net/2010/01/my-honest-consumer-opinion-of-the-ipad-who-cares/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 06:48:39 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=172</guid>
		<description><![CDATA[I can&#8217;t speak for the whole of technology consumers when I say that the Apple iPad, which debuted a few days ago in Apple&#8217;s Keynote, doesn&#8217;t seem terribly interesting. I&#8217;ll admit that I tend to roll on gut instinct when gauging the success of a potential product. I&#8217;ve done it as both a member of [...]]]></description>
			<content:encoded><![CDATA[<p>I can&#8217;t speak for the whole of technology consumers when I say that the Apple iPad, which debuted a few days ago in Apple&#8217;s Keynote, doesn&#8217;t seem terribly interesting. I&#8217;ll admit that I tend to roll on gut instinct when gauging the success of a potential product. I&#8217;ve done it as both a member of a startup and a tech industry observer. The question that always bugs me is: If Apple hadn&#8217;t set a price at $499, how much would I be willing to pay for such a device?</p>
<p>Maybe $200, and I&#8217;m not even sure about that.</p>
<p>The real issue at hand is not me being stingy. It&#8217;s me weighing the economical pros and cons of owning such a device over something like a laptop or netbook. What can I get out of something already being billed as &#8220;A Giant iPhone?&#8221;</p>
<p>I feel as if the iPad is making consumers think &#8220;that would be cool to have,&#8221; while in the past, the iPod Touch and iPhone Keynote was making people like me practically drool while screaming &#8220;I WANT THAT!&#8221; In fact, I own an iPod Touch, and it is every bit as spectacular as I thought it would be. But I digress, the point is that I was absolutely convinced that I <em>needed</em> an iPod Touch. It had WiFi built in, a web browser, mp3 player, video player, photo viewer, an endless library of applications, mobile iTunes &#8212; the list goes on! The iPad doesn&#8217;t offer much more, and it doesn&#8217;t fit in my pocket.</p>
<p>I will say this: It was probably the vibe that Steve Jobs was going for in his KeyNote (sitting in a comfortable looking chair with an iPad on his lap), but the iPad would probably make a great coffee table piece. You can pick it up at-will, check your email, surf the web, check the weather, watch videos, and oh &#8212; read an ebook. But I&#8217;ll be honest, the iPad isn&#8217;t going to really compare to a Kindle. The Kindle is easy on the eyes, has three times the battery life, and is easier to handle and take with you.</p>
<p>So you may be thinking, &#8220;well Kenny, there have been a lot of positive reviews for the iPad!&#8221; I don&#8217;t doubt it. In fact, everything that I&#8217;ve ever tried that has Apple&#8217;s logo on it has been awesome. Macbooks, iPods, Apple II&#8217;s, every piece of Apple software ever written (iLife), it&#8217;s all fantastic. But there was a certain sect of people that <em>needed</em> those devices or software. I&#8217;m just not sure that kind of need exists for the iPad.</p>
<p>It&#8217;s kind of like Google Wave. It was kind of cool, and still has a lot of potential. Hell, I was one the the first people signing up for a beta account just because I wanted to see what all the hype was about. But it seems as though the world just doesn&#8217;t need it.</p>
<p>Any technology like Wave or the iPad will have its share of mindless early-adopting brand zombies. Some people still insist that Google Wave is really useful and has a shot at changing the innerwebs. I don&#8217;t buy that one either, mainly because after I tried it, my instinct asked me, &#8220;how does it help me? how can it help you do what you do more efficiently?&#8221; I don&#8217;t know the answer to that yet, and that&#8217;s why I don&#8217;t quite believe in it as a product.</p>
<p>Like I said, I don&#8217;t speak for every consumer, so I will not truly know how the iPad (or Wave for that matter) will fair. But my own personal reaction to the Apple Keynote was &#8220;Hey, you can&#8217;t win&#8217;em all! They still have other great products. Maybe I&#8217;ll start looking into Amazon shares.&#8221;</p>
<p>Oh yea, the iPad is already the subject of internet hilarity:</p>
<p><a href="http://www.collegehumor.com/video:1928558"><img class="alignnone size-medium wp-image-173" title="play-ch-ipad" src="http://codefury.net/wp-content/uploads/2010/01/play-ch-ipad-300x171.png" alt="" width="300" height="171" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/01/my-honest-consumer-opinion-of-the-ipad-who-cares/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MiFi &#8211; An Aircard Alternative for Linux, Mac &amp; Windows</title>
		<link>http://codefury.net/2010/01/mifi-an-aircard-alternative-for-linux-mac-windows/</link>
		<comments>http://codefury.net/2010/01/mifi-an-aircard-alternative-for-linux-mac-windows/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 18:03:04 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=163</guid>
		<description><![CDATA[I intend to finish my previous post about fixing up caching in CodeIgniter, but I wanted to write a blurb about a device that I just picked up today &#8212; the MiFi. I thought I should mention some of the highlights of the product, some points that weren&#8217;t immediately apparent when I was researching it, [...]]]></description>
			<content:encoded><![CDATA[<p>I intend to finish my previous post about fixing up caching in CodeIgniter, but I wanted to write a blurb about a device that I just picked up today &#8212; the <a href="http://www.novatelwireless.com/MiFi2200">MiFi</a>. I thought I should mention some of the highlights of the product, some points that weren&#8217;t immediately apparent when I was researching it, and some tips that could save you <a href="http://forums.wireless.att.com/cng/board/message?board.id=pccards&amp;thread.id=12093&amp;page=3">thousands in overage charges</a>.</p>
<p>I bought the MiFi, which was developed by Novatel Wireless, through Verizon. It&#8217;s a standalone mobile wireless router that acts like a traditional aircard. It uses Verizon&#8217;s 3G network for internet access, and puts out an 802.11b/g signal so up to five devices can connect to it at a time. Here&#8217;s a picture of it with my iPod Touch:</p>
<p><img class="alignnone size-medium wp-image-167" title="0125001131" src="http://codefury.net/wp-content/uploads/2010/01/0125001131-300x225.jpg" alt="" width="300" height="225" /></p>
<p>Area-wise, it is about the size of a credit card. In terms of thickness, it&#8217;s about 1/3 of an inch (~8.5 mm).</p>
<p>I&#8217;ve recently picked up a 6-month freelance contract at a <a href="http://hugeinc.com/">design firm in Brooklyn</a>, which is probably an hour and a half commute by train and subway. When thinking about the amount of time I&#8217;d be spending on the train, I immediately realized it would be wise to look into an aircard for my laptop so I could both browse and get some work done during the commute. There were a few big requirements that I had, but my initial research on the websites of wireless providers failed to answer all of my questions.</p>
<p>I&#8217;m writing this post to offer some answers to questions others might have about the MiFi.</p>
<p>When searching for an aircard, I had some requirements:</p>
<ul>
<li>It must play friendly with Windows, Mac, and Linux, because I use all three</li>
<li>It must have some common connection interface like USB &#8212; Expansion cards won&#8217;t do</li>
<li>It can&#8217;t have a goofy form factor, like a USB stick just asking to be knocked out of its slot</li>
<li>I&#8217;d rather I didn&#8217;t have to install evil-ware to use it</li>
<li>I can try before I buy</li>
<li>I want to be able to easily check that I&#8217;m not exceeding my data plan allowance</li>
<li>There must be positive reviews for the product</li>
</ul>
<p>Does it sound like I had some seriously stringent requirements? Probably, but the MiFi passed most of those. Let me roll through each.</p>
<p>Win/Mac/Linux compatibility: This isn&#8217;t so much to ask, but Linux tends to be under-supported in the aircard world. Initially, I wanted to learn exactly what kind of computers could use the MiFi. The answer, of course, is any computer that is WiFi enabled. The only catch is that the card has to be activated using VZAccess Manager (VZAM) which only runs in Windows and Mac OSX. After you activate the card, you can take it anywhere, connecting any devices that talk WiFi to the web, neglecting the box that actually has the software installed.</p>
<p>I&#8217;m sure I could have done this on my linux box in a Windows VM, but I decided to take the easy route and stick it on my secondary box at home (Windows 7). Actually, that&#8217;s something that wasn&#8217;t noted anywhere: The software is compatible with Windows 7. Alternatively, I believe you can attempt to do this online if you have an account set up on your cell provider&#8217;s website, and forgo VZAM altogether.</p>
<p>I answered the &#8220;common interface&#8221; question with the last point, so I&#8217;ll talk about form factor. The MiFi is literally small enough to fit in your pocket, although I wouldn&#8217;t recommend doing that. When you plan to use it, turn it on, and sit it on a table or place it in your bag. Then you can turn on your laptop and connect to your MiFi network, which will named something like &#8220;MiFi2200xxxxxxxx&#8221;. When you are done, it might be wise to turn it off. The device can apparently go into standby for 40-something hours, but I have thought of some real issues which I will talk about. While being used, the device will last about 4 1/2 hours.</p>
<p>I was told by the sales rep that if I had an issue or was dissatisfied, I could return the MiFi for a refund within 30 days. This isn&#8217;t quite a &#8220;try before you buy,&#8221; because I shelled out ~$189 with a 1 year contract. But if I need to, I can return the item to get my $189 back and a premature exit from the contract.</p>
<p>As for positive reviews &#8212; I only buy items that have been positively reviewed. <a href="http://www.boygeniusreport.com/2009/09/15/sprint-mifi-verizon-mifi-road-tested/">The MiFi is no exception</a>.</p>
<p>In total, I paid $189 for the device, and received a $50 mail-in rebate. Verizon has two data plans: $39.99 for 250 MB, and $59.99 for 5GB. For the first, any overage is charged at 10 cents per MB. For the second, it&#8217;s 5 cents per MB. I selected the $59.99/month 5-GB data plan. You might be thinking, 5GB? That&#8217;s too low! Sadly, there aren&#8217;t any wireless providers that go above this threshold. As far as I know, Sprint, AT&amp;T, and Verizon all have the exact same pricing and cap for their aircards. Sorry, we can&#8217;t get around this one.</p>
<p>That last point brings me to my next.<strong> Beware of processes on your machine which might use your internet connection in the background</strong>. The biggest offender I can think of it <strong>Windows Update</strong>. Consider the naive aircard customer who says to the Verizon sales rep, &#8220;Well, I will only be checking my email periodically while I work. That is the biggest reason I need it.&#8221; The Verizon rep then recommends the 250MB plan because it sounds like a good fit. Wrong!</p>
<p>You can&#8217;t really hold it against the two parties in this situation, because the customer it thinking her data usage will be light. The Verizon rep is not a computer expert in any sense of the  term, and also thinks the plan would be fine. But think about the types of processes that exist (specifically for Windows), that take your internet connection for granted.</p>
<p>Windows update, for instance, will literally download hundreds of megabytes worth of data quietly in your system tray. Sun Microsystems&#8217; Java updates will do the same. I certainly hope any aircard customers aren&#8217;t victims of spyware or malware, which will covertly send and receive data behind the scenes, eating up the usage allowance. Users will want to carefully check that any file sharing or torrent clients aren&#8217;t running in the background. Accidentally leaving one of those guys open can be a mistake worth thousands of dollars. And since you can connect up to 5 devices at a time, you might want to be wary of which computers you are sharing your connection with.</p>
<p>Luckily, if you point your browser to the standard router address http://192.168.1.1, you will find that you have a neat control panel that gives you information on your current connection. Here&#8217;s a screenshot below:</p>
<p><a href="http://codefury.net/wp-content/uploads/2010/01/Screenshot-MiFi-Admin.png"><img class="alignnone size-medium wp-image-165" title="Screenshot-MiFi-Admin" src="http://codefury.net/wp-content/uploads/2010/01/Screenshot-MiFi-Admin-276x300.png" alt="" width="276" height="300" /></a></p>
<p>If you want to edit the default settings of your network, such as the SSID or network key, you need to login to the box on the top-right portion of the page. Verizon did not print the initial password for the administration section <strong>anywhere</strong>. So I went digging on the Novatel wireless website and found that the default password is <strong>admin</strong>. Funny, that used to be the standard default password for Linksys routers too.</p>
<p>There are a surprising number of options. For instance, you can filter out certain MAC addresses from using your network, set up port forwarding (albeit on a very limited scale), and change your security configurations:</p>
<p><a href="http://codefury.net/wp-content/uploads/2010/01/Screenshot-MiFi-Settings.png"><img class="alignnone size-medium wp-image-166" title="Screenshot-MiFi-Settings" src="http://codefury.net/wp-content/uploads/2010/01/Screenshot-MiFi-Settings-276x300.png" alt="" width="276" height="300" /></a></p>
<p>In the end, the MiFi seems to be a pretty cool device. But I was watching my usage climb by kilobytes when logged into the admin panel, even when I wasn&#8217;t actively using my connection. Background processes? Maybe. But I sure hope it doesn&#8217;t run up my bill.</p>
<p>As a side note, before you take the plunge with one of these things, do your research online. I found that asking the sales people at the Verizon store questions on the technical side didn&#8217;t yield any answers. Although, when I asked one rep whether a USB aircard I was looking at would work with Linux, he said &#8220;Well, Linux is based on Windows, so yes.&#8221; I guess <a href="http://en.wikipedia.org/wiki/Unix">Dennis Richie and Ken Thompson</a> of Bell Labs <a href="http://en.wikipedia.org/wiki/Back_to_the_future">got in their &#8216;82 Dolorian</a> and robbed the Windows source code from Bill Gates, then traveled back to 1969 and released Unix.</p>
<p>Convincing.. Just kidding. But do your research before you walk in the door. That&#8217;s all.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2010/01/mifi-an-aircard-alternative-for-linux-mac-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flushing CodeIgniter&#8217;s URI-based Cache (Part I)</title>
		<link>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/</link>
		<comments>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 04:49:33 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP Development]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=152</guid>
		<description><![CDATA[CodeIgniter&#8217;s output caching mechanism &#8212; at least in my opinion &#8212; has limited usefulness. It can be used to cache the final payload sent to the user for a given number of minutes. But sometimes clearing the cache for all pages or a specific page can be useful, especially if keeping the user from seeing [...]]]></description>
			<content:encoded><![CDATA[<p>CodeIgniter&#8217;s output caching mechanism &#8212; at least in my opinion &#8212; has limited usefulness. It can be used to cache the final payload sent to the user for a given number of minutes. But sometimes clearing the cache for all pages or a specific page can be useful, especially if keeping the user from seeing stale data is important.</p>
<p>This post will discuss what caching is, and how it is used in CodeIgniter. The next post will provide a few helper methods for clearing caches for specific pages (or really, URIs). I think this will make CI&#8217;s caching feature a lot more usable.</p>
<p>In a nutshell, this is how (and why) output caching is typically implemented:</p>
<p>Suppose we have a page at http://mysite.com/stats/website which loads and shows all the statistics about the users on my site, activity, files posted, etc. In other words, a lot of SQL queries (maybe 40 or so) and calculations go into this page. That takes significant time and resources.</p>
<p>Now imagine that this page is particularly popular. Maybe a heavily-read blog or bookmarking service links to your website, and you receive an unexpected burst in traffic. All of those page loads are re-running your calculations and queries, and that is consuming serious memory and CPU cycles. The number of requests your website can serve per-minute is now falling through the floor!</p>
<p>The idea of caching involves using the fact that our page probably doesn&#8217;t need calculate those statistics or run those queries every time. Perhaps gathering all of that data once an hour would suffice.</p>
<p>&#8220;Caching&#8221; involves generating the statistics page like we normally would, but saving a copy of the output we were going to send to the user for a certain amount of time. During that time period, everyone who requests that page will get the same page output that we generated x minutes ago.</p>
<p>After that time period passes, and we receive another page request, we recalculate the stats, and send them to the user. Of course, we&#8217;ll save the newer stats for a given amount of time for subsequent requests.</p>
<p>This basic caching &#8212; &#8220;page caching&#8221; &#8212; is the kind that CodeIgniter offers.</p>
<p>When you are inside a controller, you can tell CodeIgniter that you want to cache any requests to the current URI for <strong>n</strong> minutes. For that time period, you only want to send the output your are about to generate.</p>
<p>This is how it looks:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Stats <span style="color: #000000; font-weight: bold;">extends</span> Controller
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">function</span> website<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// 40 SQL Queries (Maybe a little overboard)</span>
    <span style="color: #666666; font-style: italic;">// Serious, ultra-precise calculations</span>
    <span style="color: #666666; font-style: italic;">// More intensive code that isn't good for fast page loads</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Tell CI you want to cache the output of this page for 10 minutes.</span>
    <span style="color: #666666; font-style: italic;">// This means that for the next 10 minutes, when CodeIgniter receives</span>
    <span style="color: #666666; font-style: italic;">// a request for stats/website, the CI system will not even consult this</span>
    <span style="color: #666666; font-style: italic;">// method or instantiate this controller. It will serve a static page containing</span>
    <span style="color: #666666; font-style: italic;">// the exact content that you output here.</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">cache</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'stats/website'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And that&#8217;s all you have to do! In this example, CodeIgniter&#8217;s output caching works great.</p>
<p>So then, what were the qualms I mentioned earlier?</p>
<p>Suppose we also cache user profile pages, which might be located at a URI similar to http://mysite.com/users/profile/kennyk. For whatever reason, we will assume that caching this page could be very beneficial due to heavy traffic on the site.</p>
<p>If a user profile is cached for 10 minutes, and a user updates his profile in some profile editing area, he will still see the older version of his profile page when he tries to view it. This can be confusing and inconvenient.</p>
<p>Other MVC frameworks (like Rails) handle this issue in a snap by allowing the developer to &#8220;sweep&#8221; caches at will. CodeIgniter does not offer any functionality similar to this.</p>
<p>My next post will document a cache helper I&#8217;ve whipped up to allow CodeIgniter to sweep caches for a given URI. Look out for &#8220;Flushing CodeIgniter&#8217;s URI-based Cache (Part II).&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2009/12/flushing-codeigniters-uri-based-cache-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Insert Multiple Rows Into A Database with CodeIgniter</title>
		<link>http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/</link>
		<comments>http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 19:21:15 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=135</guid>
		<description><![CDATA[When using a spiffy web application framework like CodeIgniter for PHP, I tend to start depending on the framework for a lot of functions.
For example, if I want to get the segments of the URI, I first think, &#8220;CodeIgniter must have that!&#8221; If I want a function to convert input from a &#60;textarea&#62; into correctly [...]]]></description>
			<content:encoded><![CDATA[<p>When using a spiffy web application framework like CodeIgniter for PHP, I tend to start depending on the framework for a lot of functions.</p>
<p>For example, if I want to get the segments of the URI, I first think, &#8220;CodeIgniter must have that!&#8221; If I want a function to convert input from a &lt;textarea&gt; into correctly formatted html, I think, &#8220;CodeIgniter must have that!&#8221;</p>
<p>And when CodeIgniter doesn&#8217;t have a function that would be really useful, I tend to think, &#8220;Now what?&#8221;</p>
<p>One commonly found problem is that CodeIgniter doesn&#8217;t have a specific function for inserting multiple rows into a database at once. It&#8217;s obvious that if you need to insert over 10 rows &#8212; you should really be doing it in as few queries as possible. There have been <a href="http://codeigniter.com/forums/viewthread/94459/">some blog posts asking about this</a> on the CI forums. It&#8217;s not a tough problem to solve by any stretch &#8212; but I wanted to write an extension of the Model class with a function to do this as quickly and efficiently as possible.</p>
<p>Right now I&#8217;m working on a webapp where I need to allow one user to send a message to potentially thousands of other users. That means I&#8217;ll need thousands of database inserts. Doing this with individual queries could take minutes. Inserting them in bulk would take under half of a second.</p>
<p>The code that I wrote has been tested and benchmarked to be as fast as I could possibly make it. I used PHP&#8217;s built in array_walk functions (which are written in C) over my own. A few other optimizations are present as well.</p>
<p>I posted <a href="http://codeigniter.com/wiki/Inserting_Multiple_Records_Into_a_Table/">this code over on the CodeIgniter wiki too.</a></p>
<p>The first thing you need to do is extend the model class (if it isn&#8217;t already extended), with the following code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> MY_Model <span style="color: #000000; font-weight: bold;">extends</span> Model <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> MY_Model<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span><span style="color: #004000;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * A method to facilitate easy bulk inserts into a given table.
     * @param string $table_name
     * @param array $column_names A basic array containing the column names
     *  of the data we'll be inserting
     * @param array $rows A two dimensional array of rows to insert into the
     *  database.
     * @param bool $escape Whether or not to escape data
     *  that will be inserted. Default = true.
     * @author Kenny Katzgrau 
     */</span>
    <span style="color: #000000; font-weight: bold;">function</span> insert_rows<span style="color: #009900;">&#40;</span><span style="color: #000088;">$table_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$column_names</span><span style="color: #339933;">,</span> <span style="color: #000088;">$rows</span><span style="color: #339933;">,</span> <span style="color: #000088;">$escape</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">/* Build a list of column names */</span>
        <span style="color: #000088;">$columns</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">array_walk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$column_names</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'prepare_column_name'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$columns</span>    <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$column_names</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Escape each value of the array for insertion into the SQL string */</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$escape</span> <span style="color: #009900;">&#41;</span> <span style="color: #990000;">array_walk_recursive</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$rows</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'escape_value'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Collapse each rows of values into a single string */</span>
        <span style="color: #000088;">$length</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rows</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$length</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$rows</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$rows</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Collapse all the rows into something that looks like
         *  (r1_val_1, r1_val_2, ..., r1_val_n),
         *  (r2_val_1, r2_val_2, ..., r2_val_n),
         *  ...
         *  (rx_val_1, rx_val_2, ..., rx_val_n)
         * Stored in $values
         */</span>
        <span style="color: #000088;">$values</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;(&quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'),('</span><span style="color: #339933;">,</span> <span style="color: #000088;">$rows</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;)&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;INSERT INTO <span style="color: #006699; font-weight: bold;">$table_name</span> ( <span style="color: #006699; font-weight: bold;">$columns</span> ) VALUES <span style="color: #006699; font-weight: bold;">$values</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">simple_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> escape_value<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;'&quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;'&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> prepare_column_name<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;`<span style="color: #006699; font-weight: bold;">$name</span>`&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That file, My_Model.php, should be placed in your system/application/libraries folder. Next, you need to modify the model which needs to insert multiple rows. In my case, I want my Message model to be able to insert a lot of messages, so I&#8217;ll add &#8216;extends MY_Model&#8217; to its class definition.</p>
<p><strong>Note:</strong> The <strong>MY_</strong> prefix is the default prefix used to extend a class in CodeIgniter. If you have modified this in your <strong>config.php</strong>, use your prefix as appropriate.</p>
<p>This is my new model, which contains an example usage of the method (but real usage would likely be a little more involved).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Messages <span style="color: #000000; font-weight: bold;">extends</span> MY_Model 
<span style="color: #009900;">&#123;</span>   
  <span style="color: #666666; font-style: italic;">/* Code .. */</span>   
  <span style="color: #000000; font-weight: bold;">function</span> InsertTestData<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>   
  <span style="color: #009900;">&#123;</span>     
    <span style="color: #666666; font-style: italic;">/* Prepare some fake data (10000 rows, 40,000 values total) */</span>
    <span style="color: #000088;">$rows</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_fill</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10000</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">34239</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">102438</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;Test Message!&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'2009-12-12'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$columns</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'to_user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'from_user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'message'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'created'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">insert_rows</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'messages'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$columns</span><span style="color: #339933;">,</span> <span style="color: #000088;">$rows</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The insert_rows method will automatically escape your data for the query, which tends to take up a healthy portion of this script&#8217;s running time. After all, it has to check 40,000 values, and escape 10,000!</p>
<p>If you need to insert something like 10,000 or 20,000 rows, it is recommended that you page through the values you are inserting. Otherwise, you run the risk of exceeding memory limits, or MySQL&#8217;s maximum packet size.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2009/12/insert-multiple-rows-into-a-database-with-codeigniter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Add Files to Subversion Recursively</title>
		<link>http://codefury.net/2009/12/add-files-to-subversion-recursively/</link>
		<comments>http://codefury.net/2009/12/add-files-to-subversion-recursively/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 17:03:56 +0000</pubDate>
		<dc:creator>Kenny Katzgrau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codefury.net/?p=129</guid>
		<description><![CDATA[Adding a directory and sub-directories to your subversion repo: I&#8217;ve seen some wacky solutions to this problem online, and a lot of people don&#8217;t know this is a built-in command (Google &#8220;add files to subversion recursively&#8221;).
Since CodeFury has been getting pretty high in the Google listings, I&#8217;ll post the real command. Hopefully subversion users will [...]]]></description>
			<content:encoded><![CDATA[<p>Adding a directory and sub-directories to your subversion repo: I&#8217;ve seen some wacky solutions to this problem online, and a lot of people don&#8217;t know this is a built-in command (Google &#8220;add files to subversion recursively&#8221;).</p>
<p>Since CodeFury has been getting pretty high in the Google listings, I&#8217;ll post the real command. Hopefully subversion users will find my blog before running someone else&#8217;s 50 line perl script.</p>
<p>And here it is:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">svn</span> add <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #660033;">--</span> force</pre></div></div>

<p>It would really be scary to consider what would happen if subversion didn&#8217;t have this in it&#8217;s toolbox. Rails developers would be in tears any time they ran</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">script<span style="color: #000000; font-weight: bold;">/</span>generate <span style="color: #7a0874; font-weight: bold;">&#91;</span>something<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #666666; font-style: italic;"># Generating n new files in n directories ... ;)</span></pre></div></div>

<p>Of course, even that command isn&#8217;t as easy as git&#8217;s</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git add .</pre></div></div>

<p>I&#8217;ve been using git full force lately. I&#8217;m not entirely in agreement with <a href="http://en.wikipedia.org/wiki/Git_%28software%29#Early_history">Linus Torvalds&#8217; quips on subversion</a>, but I do agree that git is superior to svn in a lot of ways.</p>
<p>Anyway, I hope this post saves someone a lot of typing.</p>
]]></content:encoded>
			<wfw:commentRss>http://codefury.net/2009/12/add-files-to-subversion-recursively/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
