Merry Christmas
From all of…well…me to all of you:
Have a very Merry Christmas.
From all of…well…me to all of you:
Have a very Merry Christmas.
A cursory glance around the web will reveal a ton of PHP-based random string generators. With enough looking you’ll find generators that do any of the following:
Problem is, none of them ever incorporated all this functionality. Every generator was a hodgepodge, e.g. some forced inclusion of numbers, or allowed either upper or lowercase, not both. All of these are great options, and it would be great to have all of them at your disposal in one tight function.
No more! I got so sick of finding shortcomings that I finally just put it all together myself. The following function allows you to choose a string length, as well as the character sets to use when building your random string. You can even include a set more than once, giving greater usage weight to certain characters. Finally, complete flexibility!
function koehl_generator($length = 10, $charsets = 'lower') { $upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $lower = 'abcdefghijklmnopqrstuvwxyz'; $numbers = '1234567890'; $symbols = '!@#$%^&*()-_=+<>,.?/:;[]{}|~'; if (!is_array($charsets)) $charsets = array($charsets); $charset_pool = array(); foreach ($charsets as $set) { $charset_pool[] = $$set; } $max = (sizeof($charset_pool) - 1); $v = ''; for ($i = 0; $i < $length; $i++) { $this_pool = $charset_pool[rand(0, $max)]; $v .= $this_pool[(rand() % strlen($this_pool))]; } return $v; } // usage examples echo koehl_generator(10, 'upper') . '<br />'; echo koehl_generator(10, 'lower') . '<br />'; echo koehl_generator(10, 'numbers') . '<br />'; echo koehl_generator(10, 'symbols') . '<br />'; echo koehl_generator(10, array('upper', 'lower')) . '<br />'; // order of the array in the second argument does not matter echo koehl_generator(15, array('lower', 'upper', 'numbers')) . '<br />'; echo koehl_generator(15, array('lower', 'numbers', 'upper')) . '<br />'; echo koehl_generator(15, array('upper', 'lower', 'numbers', 'symbols')) . '<br />'; echo koehl_generator(15, array('lower', 'symbols')) . '<br />'; // note how often letters appear in the next one echo koehl_generator(20, array('lower', 'lower', 'numbers')) . '<br />';
Adding your own custom set is easy too. Include a new set following the syntax of the existing ones, then call your new set by variable name in the second argument…
// add this to the top of the function... $the_basics = 'abc123'; // then use it like so... echo koehl_generator(5, 'the_basics') . '<br />'; echo koehl_generator(10, array('the_basics', 'symbols')) . '<br />';
If you find this useful, please be sure to give me some link love, just a reference URL to this page in your code would be fine. Using the share buttons below would be great as well!
I’ve learned that one of the biggest office-cluttering offenders when you run a company is receipts. The government wants to see them for tax purposes, so you hold onto every last one to save every last dollar. The problem, of course, is that you’ll collect a crap ton of these stupid little bits of paper over the course of a year, they don’t file well, and certain types of paper fade over time.
Enter the NeatReceipts Mobile Scanner, which I recently purchased to help eliminate my paper bloat. Scans full-size pages, business cards, and all manner of receipts. Then it will catalog them for you. Nice.
I of course was one of the lucky ones to run into a weird install issue. The system uses a trimmed down version of Microsoft SQL Server to store its data, and the server simply would not install. A quick online chat with a customer support rep from The Neat Company, and a tech was remotely diagnosing the problem in a few minutes. No hoops, no “check your cables” nonsense, just a few up front questions and then she was on it. I was honestly impressed with her speed and professionalism.
Until we diagnosed the problem, anyway. Allow me to summarize the end of our exchange. (We used LogMeIn Rescue—great software—and I did not realize until afterwards that chat logs are not saved locally. Lesson learned.) While attempting to run a fixup batch file, she consulted with her manager on an error that popped up. The meat of the message was that wmiprvse.exe hit an error at a “procedure entry point” in fastprox.dll. I don’t speak Microsoftish fluently, but she was helpful enough to point out that the core problem lay with my installation of Windows Management Instrumentation, or WMI for short. This was a specialized issue, would require direct intervention from Microsoft staff to correct, and I would have to contact Microsoft to fix the problem.
The end result: I was on my own to fix the problem.
At that point, I had entered the feared “other guy zone.” This is what you enter when you have an issue that offers an “out” to the support line you called. You know, “It’s not us, it’s the other guy. Our [printer / router / hardware] merely uncovered a preexisting issue with your existing [operating system / internet connection / software], and you’ll have to contact [insert vendor name here] to get the problem rectified.” In a former life I did phone support, and I continue to provide direct support to end users in homes and businesses, so I’ve been on both ends of this conversation countless times.
The problem here is obvious: with the “right” problem (or the “right” explanation from the poor end user), your can end up in an endless loop of support calls. These problem seems to exist just outside the boundaries of whichever vendor to whom you are talking. [A] refers you to [B], who refers you back to [A]. God help you if [A] refers to [B] who refers to [C]; I advise you throw you up the white flag right and just return the product. Your remaining mental faculties may be at risk if [D] enters the picture.
The reality, of course, is in the middle. Some problems really are outside of the control of [vendor], but there are also plenty of times where [vendor] is simply being lazy. The customer is stuck in a Möbius strip of support teams, each blaming the next. If anyone is going to break the customer out, one of them is going to have to step up to the plate, take charge, and see to it that the problem is fixed. Otherwise the customer will eventually give up, return the product, and send their business elsewhere.
As end users, we are all screaming the next question: “Why don’t companies recognize this? Now, why doesn’t every company take this to heart in their support structure? Why do we hear endless horror stories about ‘customer service’ that’s anything but?”
Meanwhile, a lot of support guys respond to this line of discussion with something to the tune of, “The customer bought it, they ought to take responsibility for making it work.”
For the support reps out there, your end user question is a non-starter: all they want to do is use your widget, they could care less about how it’s done. The fact that they spent money to purchase your widget is evidence of this fact. They bought a product to simplify something in the life. Did you ever buy a product to make your life more complex?
For you end users, banging your head on the wall while on hold, let’s go back to my WMI issue. Technology is a series of dependent systems, one part builds on another. The Neat Company uses SQL Server, which uses WMI, which sits on top of Windows. If one part doesn’t work, the whole thing comes down. Neat couldn’t get SQL Server running because of WMI, and punted to Microsoft. Technically, they have pretty solid ground for doing so. The issue was “below” SQL Server, a part of the chain that they, on some level, have to assume is there and functioning properly.
However, has anyone with a standard desktop copy of Windows ever actually gotten through to Microsoft Support? I’ve been doing technical support for almost 14 years, and I have yet to get a real person on the phone, India or otherwise. If this WMI problem is “removed” for Neat Company, it’s on the moon as far as Microsoft is concerned.
In this instance, Neat Company suffers from the reality that it only has one point of view: their own. Every human being naturally looks out for themselves first (moral arguments about caring for your fellow man notwithstanding). Businesses are people, and thus are subject to the same follies.
On top of that, you have the financial realities of running a business. One of those realities is that support structures take up a cost column in the company ledger. Support is an expense, not a source of income. A business is naturally going to do everything to minimize costs, which can (and often does) affect service quality. I’m not making any claims about Neat in this regard, only pointing out what most people don’t stop to consider.
Now, all that explains why customer service sometimes fails, but it doesn’t do anything to explain why things go so awesomely well a lot of the time. My tech support agent, AJ, was great! She was on the issue immediately, and had an obvious grasp of what she was doing and how to fix the problem. When she remote’d into my desktop, I’m fairly certain the mouse was moving too fast for her to simultaneously read a stepwise guide. She also seemed genuinely disappointed that she was unable to solve my problem, maybe almost as bummed as I at the prospect of having to contact MicroMassivesoft. She didn’t finish the call until she gave me as much information about the problem as was at her disposal.
Two reasons why this happens. First people like AJ genuinely enjoy what they’re doing, which makes them better, which translates to a better customer experience. Second, there are companies out there who do in fact appreciate the value of good customer service. Think about it; the company whose customer support solves the problem, and pulls the user off the Mobius strip, will have their undying gratitude. As the problem persisted, the value in a solution increased.
By going the extra mile and solving the problem, the “winning” company walks away from the situation with a raving fan, instead of just a customer. A fan tells great stories to friends (who loves viral marketing, show of hands?), comes back for more goods and services in the future, and is harder pressed to seek alternatives from competitors. If that’s not financial incentive enough, your company might as well call it quits now, because your head is a little due south.
My rule is that a company should be an expert at diagnosing and fixing the systems with 1° of separation from the product. Running a website? You better know browsers inside and out, and have some operating system knowledge. Advertising Design? You better have a rock solid understanding of printing, and know your way around a computer. Chimney sweep? You better understand roofing and a little masonry.
In our example, Neat Company’s 1° here would definitely cover WMI issues (SQL Server -> WMI). WMI certainly overlaps enough ground that support staff should be at least versed in how to correct the most common issues.
As it turned out, AJ’s info on the issue was enough to get me going down the right path, and eventually I landed on a solution: rebuild WMI. After getting myself sorted out, I sent the steps to fix the issue back to Neat Company to help anyone else with this problem. I’m a geek, I take pity on any layperson faced with this kind of issue.
For those of you here because your own instances of Windows Management Instrumentation is busted, here’s what I did to rebuild the WMI:
net stop winmgmt%windir%\System32\Wbem\Repository folder to something else (e.g. Repository_bad)net start winmgmtrundll32 wbemupgd, UpgradeRepositorycd /d %windir%\system32\wbemfor %i in (*.dll) do RegSvr32 -s %ifor %i in (*.exe) do %i /RegServerNeat Database Setup.exe from your Neat Company setup CD or downloadSQL Server (NR2007) service is startedservices.msc)And here’s where I got it. People with more complex issues may also want to check out the WMI Diagnosis Utility. I also highly recommend that people with issues relating specifically to Neat Company products contact their customer service first. They definitely fall in the exceptional category (I’m giving AJ’s supervisor the benefit of the doubt).
5 hours later, I’m off to track down that receipt shoebox…
I’m absolutely in love with the status update stream I’ve put together for Fwd:Vault (follow link for example). However in the process, I’ve discovered a huge drawback to the Twitter messaging system: it does not store links. The Twitter site itself will identify URL’s in messages and convert them into clickable links for you automatically. But the magic ends at Twitter’s borders; anyone who wants to do the same on their site is on their own.
So I consulted the almighty Google. I found plenty of raw regex, javascript, and Twitter-focused discussions on the matter, but I found the offered solutions and tips lacking. I wanted to do this up right, transparently via PHP in the background. No JS required.
Finally, I found a small PHP script that accomplished what I needed. Here’s a renamed version—all code intact—that will find and convert any well-formed URL into a clickable <a> tag link.
Update: My buddy Tonk has updated the code to link up @replies and #hashtags as well. He also switched from POSIX to Perl regular expressions syntax, mostly cause he’s a regex dork.
function linkify( $text ) { $text = preg_replace( '/(?!<\S)(\w+:\/\/[^<>\s]+\w)(?!\S)/i', '<a href="$1" target="_blank">$1</a>', $text ); $text = preg_replace( '/(?!<\S)#(\w+\w)(?!\S)/i', '<a href="http://twitter.com/search?q=#$1" target="_blank">#$1</a>', $text ); $text = preg_replace( '/(?!<\S)@(\w+\w)(?!\S)/i', '@<a href="http://twitter.com/$1" target="_blank">$1</a>', $text ); return $text; }
Copy that into your code, then run your text containing unlinked URL’s through it. Let’s apply it to the Twitter feed example as we left it in Step 2:
<li><?php echo linkify($status->text) . '<br />' . $time_display; ?></li>
You can find this code at work on Fwd:Vault.
Build a slick Twitter feed on your site
I previously discussed why certain “automagical” features can sometimes facilitate the creation of crappy code. However they only create a possibility of crappy code. Today I want to warn you against a practice that will create crappy code 100% of the time.
First a scenario – you have written a program in your language of choice. It’s fairly complex, partially because of the basic needs of your client or employer, and partly because every project is a moving target to a certain extent. At some point in the logic flow, your code behaves aberrantly; let’s keep it really simple and say that it’s outputting dashes instead of spaces in a block of text. “Well these shouldn’t be here at this point,” you think. “That text was scrubbed out when it came out of the database.” You confirm the scrubbing occurs, and check some things along the way to the output. Everything checks out.
However there’s a huge nebulous area that you conveniently sidestep, a big ol’ chunk of code written by Larry. The same Larry who got fired last month for half-assing that reporting module for the marketing team. A piece of his code still sits between your perfect database setup and your equally perfect outputting logic. You don’t want to touch Larry’s code with a 10-foot pole. “The problem MUST be in there,” you decide. “I’ll just undo the text change on the other side and be done with it.”
In other words, you treated the symptom, and didn’t solve problem. This time-saving decision, while fairly innocent on its own, has far-reaching consequences for both your software and your own career as a developer. None of them are good.
Because you did not identify for certain where the problem lies, you have absolutely zero guarantee that Larry’s code is the problem at all. It could very well be in Larry’s code, but you didn’t look everywhere so you can’t say for sure.
The symptom you treated may well lead to a much larger problem. Perhaps it’s not only replacing spaces with dashes, but also truncating the text beyond a certain length. You won’t see that until a long-enough string passes by, and it may not pass by a person’s eyes for even longer. That’s the nasty thing about bugs, a human being must find and remove them. No matter what your philosopher-slash-uber coder friend says, the Matrix and its self-making code does not exist, so get in there and clean up the mess.
In short, with that one move, you’ve started down the path of writing crappy code. Keep taking that shortcut, and it won’t be long before you’re fired too, because your code will be a bug-ridden mess. Kind of like Larry, right? That because it’s the same path taken by Larry and every other lazy coder you’ve ever known.
The good news is that this path is easily avoidable: don’t be lazy. Do the work right the first time, stick with your syntax rules, and get to the root of every problem, every time.
Also, if the hypothetical scenario sounds eerily familiar, you might want to finish reading this post and go double-check that page slug creation code you wrote.
I awoke to an e-mail this morning containing the following…
We are sad to announce that Pownce is shutting down on December 15,
2008. As of today, Pownce will no longer be accepting new users or new
pro accounts.To help with your transition, we have built an export tool so you can
save your content. You can find the export tool at Settings > Export.
Please export your content by December 15, 2008, as the site will not
be accessible after this date.Please visit our new home to find out more:
http://www.sixapart.com/pownce
Our thanks go out to everyone who contributed to the Pownce community,
The Pownce Crew
If you’re not in the know—there are quite a few of you, apparently—Pownce was “a way to keep in touch with and share stuff with your friends. Send people files, links, events, and messages and then have real conversations with the recipients” (from the Pownce homepage). In other words, share stuff. Stuff that can be shared via any other social networking site. I would argue that sharing stuff is the focus of the web itself, and that social networking is merely a focused version of the web’s core purpose, but that’s a different topic.
Social networking is just like any other market, it has a saturation point, and the weaker players will eventually close up if they are unable to make a dent in market hold. Pownce certainly had its unique traits (the desktop client was a neat idea), but ultimately it wasn’t enough.
The good news for you Pownce fans is that it looks like the service was actually bought by Six Apart, so you may see the same tech pop up in their Vox service. For its part, Six Apart looks more and more like a conglomerate of moderately successful web properties leveraged to sell advertising and overpriced buzz-wordy services to unsuspecting companies.
At first glance. I could be wrong.
Moving on, I don’t think Pownce going under is the big news; web properties pop up and fade away all the time. I feel the real point of discussion is that media-proclaimed new-age mogul Kevin Rose was a Pownce co-founder. Seeing as how it’s actually a sale and not a shutdown, I’m sure he’ll come out ahead financially, good for him. But most articles covering him fawn over his ability to turn seemingly any website he touches into gold. The cover story in a recent issue of Inc. Magazine is a great example of the perception (look at the url). However a sellout seems to fly in the face of the image we typically get of Rose.
There are only three reasons for selling a business:
I don’t suspect that Rose simply wanted to get out, the property only boosts his cred as “the next Rupert Murdoch,” as described by Jeff Jarvis in the Inc. article. So he either expected to sell out, or failed to make it profitable which, again, runs counter to Rose’s pop image in business circles.
Don’t get me wrong, the guy’s talented. But superhero status has the same effect as a nonsensical buzzword: they generate an inaccurate and wholly unattainable image for the uninformed, making business dealings more difficult. “We’re looking to [blah blah blah], like Kevin Rose.” I still have clients describing their need for a “synergistic solution.” So I’m hoping that the Pownce sale bring the down the fever pitch surrounding Rose a little bit.