Saturday, April 12. 2008Las Vegas PHP Group: It's AliveAs promised, a couple of days ago the LV PHP User Group had its first meeting. The purpose of the meeting was to see what kind of interest there was and to gather some ideas for future meetings. We had a pretty good turnout for our first meeting. I think around 20 or so people attended and we mingled and talked amongst ourselves for around 2 hours. We are going to be having another meeting in mid to late may. The current plan is that two of us will be doing a couple of short talks, I will be talking about testing and quality assurance. We also talked about getting involved in the PHP TestFest project. The last thing we decided is that the next meeting will be in a 'quieter' environment. PT's Pub worked well for a meet and greet type of meeting but would be a tad loud for any kind of presenting. It also forcluded some people from attending due to the atmosphere. When I hear more info about dates I will post it. For those of you that live nowhere near Vegas, maybe you can use us as a way to writeoff a vacation as a business expense? Thursday, April 10. 2008Las Vegas PHP User GroupI am pleased to announce that Las Vegas finally has a PHP User Group and our first meeting is...tomorrow. I am pretty excited as I know there is a fairly decent size PHP programmer community in LV, it just hasn't been organized yet. One of my co-workers Ray Lopez is organizing the group and it looks like we'll have a fairly decent size group at our first meeting. If you are from Las Vegas I would encourage you to attend if at all possible! If you are unable to attend then I would highly recommend you still sign up at meetup.com so you can keep informed of future meetings. Time:
Friday, Apr 11, 2008, 4:00 PM Monday, April 7. 2008Late Static Binding (LSB) forward_static_call()I finally freed up some time to finish some quick tests for some of the late static binding patches I made and one of them finally made it into head. The original post I had bringing up this issue was lovingly title Late Static Binding...Sorta. Basically the original patch alone did not provide a means to override a method, forward execution to the parent method and still preserve the ability for static:: to be anything meaningful. It would be turned into the syntactic equivelant of self::. I came up with a few patches to address this. After several rounds of back and forth about the patches the conversation died out with no decision. I finally resurrected the topic and was able to find concensus for the third patch (forward_static_call()). This weekend I wrapped up a few small tests and sent the patch in and it was subsequently pushed to php 5.3 and php 6.0. Now, this is not at all the way I wanted things to work, in all honesty I think the patch is pretty hokey but unfortunately nobody really spoke up in support of the changes I wanted to make to parent:: in regards to LSB. So I thought it far more important to make sure there was a way to make sure static methods could be overridden while ensuring that access to parent methods would be unabated. So now, if you want to override a static method and forward execution to the parent class, the safe way (in regards to static inheritance) is shown in Table2 while the (unfortunately) not so safe way is shown in Table1: <?php class ActiveRecord { public static funtion loadById($id, PDO $db) { $table = get_called_class(); $statement = $db->prepare(" SELECT * FROM {$table} WHERE {$table}_id = ? "); $statement->execute(array($id)); $column_values = $$statement->fetch(PDO::FETCH_ASSOC); if ($column_values) { $ar = new static($db); $ar->column_values = $statement->fetch(PDO::FETCH_ASSOC); return $ar; } else { return FALSE; } } } class Table1 extends ActiveRecord { public static function loadById($id, PDO $db) { /** * DANGER! the table name will resolve to ActiveRecord */ $ar = parent::loadById($id, $db); if ($ar === FALSE) { return new static($db); } } } class Table2 extends ActiveRecord { public static function loadById($id, PDO $db) { /** * SAFE WAY! the table name will correctly resolve to Table2 */ $ar = forward_static_call(array('parent', 'loadById'), $id, $db); if ($ar === FALSE) { return new static($db); } } } ?> This shows an example of the differences between using parent:: and forward_static_call. I really do wish that the behavior of parent:: would just be modified to work like forward_static_call does. It would be alot less awkward and imo closer to what the average oo programmer would expect. I suppose the issue is up for debate if anyone feels like bringing it up on internals, we aren't stuck with it until php 5.3 rolls In either case at least there is a way around it now... Monday, November 26. 2007Late Static Binding - Changes to parentIf you have been following the PHP internals list for the last few weeks you probably have seen a discussion concerning the current behaviour of late static binding (lsb) and how it seems to be unnecessarily limited when it comes to inheritance. I first posted about the limitations of the current lsb implementation as it relates to inheritance in Late Static Binding...Sorta. It has since been revived in this thread on the internals mailing list: RE: [PHP-DEV] late static binding php6. I won't rehash all of the arguments as you can quite easily find out my full thoughts by previous posts and on that mailing list thread. To put it simply I feel that somehow there needs to be a way to call methods in a parent class without losing the ability to reference back to the original called static. <?php class A { public static function test() { echo get_called_class(),"\n"; } } class B { public static function test() { //do additional work ... parent::test() } } B::test(); //outputs B ?> This (or anything like it) is currently impossible in the current lsb implementation. I spent a bit of my extended weekend preparing three different patches to work around this problem. I just now sent them to the internals mailing list so they can be discussed. You can view this email and get a summary of the patches by viewing my recent php-dev posting.
All of the above patches are against 5.3. I was having some strange problems with the test suite in php6 so I moved onto php5.3 so I could make sure things weren't breaking on me Tuesday, October 9. 2007ZendCon07 Day 1Day one of the conference is over and everything has gone well so far. I attended the extending PHP session by Wez, Sara, and Marcus. It was alot of review but it was very informative and brought up alot of things that I tend to forget frequently. It was also good to find out that Marcus has a pretty decent american impression. In either case I have a couple small php extension projects that I am thinking about starting now just to tinker around with some of what they talked about. I also heard some unconfirmed rumours that database testing was brought a fair amount in the Best Practices tutorial. So if any of you were in that tutorial and have any questions track me down. After the tutorials were finished all of us from the selling source decided to go into San Francisco for some food and what not. We went to the Stinking Rose which billed
itself as a garlic resteraunt and it certaintly did not dissapoint. We hung around for a while to chit-chat and what not. It is my first time in San Francisco and it pretty much
has further confirmed that I am definately not a city guy Today's sessions are underway and thus far I have found myself working the entire time but I plan on stopping that after the current round of sessions is over. I am looking forward to going to Give Your Site A Boost With memcached from Ben Ramsey and High Performance PHP & MySQL Scaling Techniques by Eli White. We will also be spending some time today setting up the Selling Source booth. We are also sponsering the opening reception tonight in the exhibit hall which I don't really think means anything other than we'll have our logo plastered in a few key places which is always nice. Also we are giving away a fairly nifty prize at the end of the conference to a random winner of a little code challenge that we put together. If any of the fellow conference goers plan on going to the opening reception be sure to track me down and say hello. I think I am going to leave both my laptop and black
berry so there will be no distractions. I would love to talk to y'all about pretty much anything. Thursday, October 4. 2007Going to ZendConI will be leaving for ZendCon on Sunday. This will be my first zend con and I am really looking forward to going. I was hoping to speak at the conference about refactoring and database testing but alas it wasn't meant to be I will be attending the conference with a sizable group of co-workers from The Selling Source and will be spending some time in our booth in the exhibit hall. If any of you would like to discuss unit testing, late static binding, or what not please come track me down. I am very interested to talk with anyone that may have checked out the PHPUnit Database extension. I have a small list of features that I am hoping to add shortly and would love to hear about any other features people may be looking for. Wednesday, September 26. 2007Late static binding....sorta :/The good news is late static binding has been introduced into head and looks like it will be merged into 5.3 before it is released. The horrible news is I really don't think the patch went as far as it needs to. If you look at the original posts that cropped up about a year and a half ago the whole purpose of late static binding was to allow the same kind of flexibility provided by inheritance of standard class methods for static methods, properties, and constants. This wouldn't really open the door for any grandios, new kind of applications, it would just allow a new way to code libraries the most prominant example being an Active Record Library. This is now possible, however I think there is a very unfortunate limitation that I brought up a few times on the Internals mailing list to apparently no avail. The problem is with the fact that static will ALWAYS return the 'resolved' name of the class used to call the current function. So, imagine the following method: class Foo { //... static public function test() { return static::$some_property; } //... } class Bar extends Foo { } If you call test using Foo::test() then static:: will resolve to the 'Foo' class. If you call it using Bar::test() then static:: will resolve to 'Bar'. This is correct and works well for simple inheritance. However things start taking a downward turn the more you use inheritance. Consider the following change to Bar and the addition of a new class Bar_Child: class Foo { //... static public function test() { return static::$some_property; } //... } class Bar extends Foo { static public function test() { // Do some work specific to Bar return parent::test(); } } class Bar_Child extends Bar { } Now, calling Foo::test() will again result in static:: being bound to 'Foo'. However, due to the fact that parent:: will resolve to Foo:: that means the call Bar::test() will now result in static:: being bound to 'Foo'. Bar_Child::test() will do exactly the same thing, static:: will again be bound to 'Foo'. This is incredibly inflexible and in my opinion this is the exact problem that 'late static binding' is SUPPOSED to fix. There are a couple of ways to fix this that I can think of right now, unfortunately nobody on list seems very motivated to explore any compromises. The two ways that come to mind immediately are either setting the behavior of parent:: such that it forwards the calling class through the next function call. So in the example above, calling Bar::test() will still result in calling Foo::test() however it will not 'reset' the calling class so that static:: will still resolve to 'Bar::', likewise Bar_Child::test() will result in static:: being bound to 'Bar_Child'. The second alternative is introducing another scope. I have no clue what this scope would be called, but it would basically implement the functionality I just described for parent:: above but would do it using a new keyword so parent:: could remain the same. Dmitry Stogov mentioned my first alternative on the list however he also included this functionality for the self:: scope which I could see causing some serious problems. In either case, I am thankful that the functionality has started to make its way in, but I can't help but think that myself and some other early proponents of the functionality are getting completely shafted. Wednesday, September 5. 2007Adding Database Tests to Existing PHPUnit Test CasesWhen I was first creating the Database Extension for PHPUnit I realized that there was a very high likelihood that several people would have tests that were already written that they would like to add additional database tests too. To accomplish this I actually wrote the PHPUnit_Extensions_Database_DefaultTester class. In fact, if you were to look at the source of the database test case you will see that all of it's operations are actually forwarded to this class which does all of the work. Please continue reading to see how you can use composition to add database tests to your existing test cases. Continue reading "Adding Database Tests to Existing PHPUnit Test Cases" Sunday, September 2. 2007PHPUnit Database Extension (DBUnit Port)I have completed the initial feature set for the Database extension to PHPUnit. This is a essentially a port of DBUnit to PHP. For those that may not have read any of my previous postings on the subject the goal of this software is to extend the functionality of PHPUnit to allow using seed data to put a given database into a known state prior to executing each test. It also provides an easy mechanism to compare database contents with an expected dataset. The database extension has recently been merged into the PHPUnit 3.2 branch and is scheduled to be released in that version. Sebastian Bergmann will be introducing the extension in his Advanced Testing with PHPUnit talk at PHP|Works 2007 in Atlanta September 13 - 14. If you would like to tinker around with the database extension prior to it's release you can always download the latest copy of PHPUnit 3.2 from svn: svn://svn.phpunit.de/phpunit/phpunit/branches/3.2. The source can also be browsed at http://www.phpunit.de/browser/phpunit/branches/3.2/PHPUnit/Extensions/Database. Please continue reading for an example of how you can now use PHPUnit to even more effectively test data-centric applications. Continue reading "PHPUnit Database Extension (DBUnit Port)" Thursday, June 21. 2007PHPDBUnit - Testing DB interaction with PHPUnitIt's been a while since I have put anything in the heavily neglected little site of mine so I thought I would start posting some updates on a few little projects I have been working on. I have been spending a considerable amount of time traveling for work so I am not quite as far along in these projects as I would like to be, but I have been making some major head way. The project I would like to talk about right now is a port of Java's DBUnit for php that will compliment the PHPUnit test suite. For those of you not familiar with DBUnit, it is a framework that allows you to easily and quickly test php code that modifies and works with database data. The whole idea behind unit testing is testing functions using well defined input and then comparing the output of that function with the values that you expect the function to produce. With database code this is somewhat difficult because you have to ensure that your database is in a known state prior to running your tests. Currenty, in order to do this properly you would find yourself adding significant amounts of code to your test to simply enter data into your database and then you will add even more code to compare the resulting database values with what your expected output. Ending up with something like this: pdo = new PDO(SOME_PDO_DSN); $this->pdo->exec("TRUNCATE test_table"); $this->pdo->exec("INSERT INTO test_table (test_table_id, col1, col2, col3) VALUES (1, 'value1', 'value2', 'value3'),(2, 'value4', 'value5', 'value6')"); $this->test_class = new Foo($this->pdo); } public function tearDown() { $this->pdo = null; } public function testDeleteByCol1() { $this->test_class->deleteByCol1('value1'); $statement = $this->pdo->query("SELECT * FROM test_table"); $rows = $statement->fetchAll(PDO::FETCH_NUM); $this->assertEquals(array(2, 'value4', 'value5', 'value6'), $rows); } } ?> This is a fairly simple example and they really only get more complicated from this point forward. In order to the equivelant test using PHPDBUnit you would create a test class as follows: test_class = new Foo($this->getConnection()); parent::setUp(); } /** Must be defined in all dbunit tests **/ protected function getDataSet() { return new PHPDBUnit_DataSet_FlatXML('_data/dataset.xml'); } /** * This is just an arbitrary function that is getting * a database connection...this could be implemented anyway * you see fit. */ private function getConnection() { /** * I don't necessarily advocate this method of getting a * connection. This part of DBUnit has just not been * implemented fully yet. */ return $GLOBALS['phpdbunit_connection']; } public function testDeleteByCol1() { $this->test_class->deleteByCol1('value1'); $this->assertDataSetEquals(new PHPDBUnit_DataSet_FlatXML('_data/expected.xml'), $this->getConnection()->getDataSet()); } } ?> You will also have to provide two xml files for the above code. This first xml file (dataset.xml) is used to seed the database before every test. The second xml file (expected.xml) is used to compare your database after the test is ran. These two files allow to get the code seeding your database out of your test cases and into their own xml files. There are also other options for generating data sets, I will discuss these options as well as the xml formats for datasets in a future post. The database connection functionality is built overtop of PDO and support is planned for all standard pdo drivers. The big question mark for me right now is the ODBC driver. The PDO connection is wrapped by a PHPDBUnit_Database class that provides the functionality to generate datasets from the database to test your data and ensure it is correct. The seeding is controlled by two functions that I did not choose to override in my example: getSetUpOperation() and getTearDownOperation(). These functions simply return a database 'operation' that is to be performed on the database connection using the data set returned by getDataSet. The default setUp operation is a clean insert. This is a truncate operation immediately followed by an insert of all data in the dataset. The default tear down operation is a null operation. You have several built-in possibilities for these operations such as Truncate, refresh, and update. You can also create your own operations if necesary. My plan is to keep the interface of PHPDBUnit as close as possible to DBUnit while maintaining a more phpish way of doing things. I am planning on the first beta release of PHPDBUnit in July. Of course I welcome feedback on any features you would like to see. In the coming days and weeks I will continue to post more information and examples of how to use DBUnit in your tests. Tuesday, January 2. 200781.4 is evilI know many of you all know pretty well that floating point precision and computers don't play nicely with each other. I think I learned about it in the first book on 'C' I ever read, but I had never really been bitten by it until today. I was working with a piece of code today at the office that was throwing an error saying two values weren't zeroing out when they clearly should have been. I narrowed down the problem and after a bit of time decided that 81.4 is a terrible, terrible number. For example: <?php $total = 100 - 81.4; //$total should be 18.6 echo "18.6 == {$total}? " . ($total == 18.6 ? 'yes' : 'no') . "\n"; var_dump(18.6 - $total); ?> So, let that be a lesson to us all. No matter how simple the calculation, don't blindly trust floats. Friday, October 27. 2006Come Work With Me!
I have recently been very encouraged by the number of job opportunities available to PHP developers lately. In light of this I thought I would make everyone aware of yet another excellent opportunity for a highly motivated, well-versed PHP programmer. The company I recently started working for (The Selling Source) is still hiring PHP Developers. I can say without a doubt that it's a great company to work for and they take very good care of their programmers. Read on for details.
Continue reading "Come Work With Me!" Thursday, August 24. 2006A New DirectionIt's been quite some time since my last blogging. Most of the reason for this is that I have been extremely busy with my current job as well as a few other responsibilities. However, the time has now come for me to move on and try something new. Early this month I accepted an offer to work for The Selling Source in Las Vegas. It is a hard move since I have been employed by my current employer, FT11 Interactive, for my entire professional career. I am looking forward to the change and the new people I will meet. Since I will be moving away from a smaller startup type atmosphere I am hoping I will have a little more time to work on some of the little projects I have been chipping away at for the last year. Late Static BindingI haven't been able to touch this in what seems like ages and have (unfortunately) completely missed the boat for PHP 5.2. But I am hoping to take a look at the current patch, come up with some solid use cases and tests, and submit the whole package to PHP Internals for review. Scriptable Browser for PHP 5.1+This is actually a fairly new project and one that I haven't put alot of time into yet. The goal behind this is to create the scriptable browser and then soon thereafter create a binding for it so it can be easily used with PHPUnit 3. I am sure there are at least 3 or 4 people wondering why I don't just work with SimpleBrowser or Selenium, and the simple answer to that is: Cause that's no fun. Refactoring ToolsThis little project is actually one that I haven't even talked about yet. I am finding that there is a real lack of tools to assist in refactoring php scripts. What tools we do have (aside from testing tools) are not at all php specific. With the advent of Greg Beaver's PHP lexer it has all of a sudden became fairly trivial to do in-depth source code analysis. I have almost completed a small code metrics suite and will (hopefully) be releasing it to the public soon. A Bigger, Badder Looking SiteI promised myself around 2 years ago that I would create a site that wasn't a s9y stock theme, I have yet to do that, so that's also going to be on my agenda for the very near future. So, I have to thank FT11 Interactive and it's management for 5 excellent years, and while I am sad to be leaving I would be lying to say I am not excited about this new opportunity. Hopefully now I can hit some of those conferences Monday, May 22. 2006Finally used PHPUnit and I like itI have been working quite a bit lately with the cvs version PHPUnit3. I have spent alot of time in testing using SimpleTest and I have also given some time to test-more.php. However, up until just recently I had honestly never used PHPUnit before. The big motivational factor for me (other than to try something new) was to see how the code coverage feature was coming along. I would have to say that after a few weeks of tinkering with it I am impressed. Now, keep in mind that I am talking about software that is still in development, so a degree of lattitude is required. The featureset of PHPUnit 3 is great. Here are a few notable features (in my mind):
Using the framework is an absolute breeze and there is excellent documentation in the form of a free book (draft version) written by Sebastian Bergmann and published by O'Reilly called "PHPUnit Pocket Guide." The API is also documented quite nicely and serves as a good second-source for learning how to do specific things. The most impressive part of this experience in my mind was how runnable the software is straight out of CVS. Most of the time when I am crazy enough to use CVS version I always seem to get my copy of the source at a point where it is very unstable and requires tweaking just to get the software to fulfill its basic requirements. PHPUnit 3 on the other hand was able to run in it's standard mode without a flaw. The only thing that was missing that I felt I needed was html reports for the pass/fail status of the unit tests. The report templates and code was already to a point however that it was actually fairly trivial for me to make the changes to it that I thought would be needed to make it work. I have since passed those changes along to Sebastian and they have been added to CVS, so html reports are now in the cvs version as well. It felt good to be able to contribute a little bit to a very worthwhile project. Sebastian has posted about the new reporting features on his blog that include some screenshots so I won't bother to rehash over all of that. You can just go check them out on his site. Friday, April 28. 2006I <3 RegexsI was toying around with regexs this morning and learned a few things I had just never taken the time to learn before. In any case, I came up with this: #((?:(?<!\\)\"(?:(?:(?:[\x20\x09]*[\r\n])?[\x20\x09]+)?(?:[\x01-\x08\x0b-\x0c\x0 (of course ignoring line breaks.) An 'atta boy' (or girl as the case may be) to anybody that can tell me what this would be used for
(Page 1 of 4, totaling 60 entries)
» next page
|
Paying for the SiteQuicksearchCategoriesArchivesDaily Readsadam trachtenberg
Ben Ramsey Chris Shiflett Dynamically Typed (Harry Fuecks) george schlossnagle John Coggeshall John Lim Marco Tabini PHP Application Tools PHPCommunity.org Planet PHP Sebastian Bergmann Sklar The PHP WTF Tobias Schlitt Tom Sommer Wez Furlong Syndicate This Blog |
