Saturday, August 18, 2007

PHP vs. RoR or Python

First: size matters.

As I understand it, and correct me if I am wrong, PHP was designed for relatively small, simple web applications and as such is reflected in its small, simple core.

Ruby, and RoR, as well as Python are true 3GL languages with applications across web and non-web domains.

Then there are frameworks, but that is another post.

Second: productivity

Related to size, how fast do you want something functional? Sure, as fast as possible, but at what cost and risk level? You can have your cake, but it's awfully darn expensive cake!

Third: runtime performance and scalability
I link these two, though you can have a fast application that doesn't scale and a slow application that scales huge. Both might be useful for some niche purposes, but for my world, most applications fall between the 2.

Feel free to chime in...my gut feel is that PHP suffices for projects that are 1) rather small, where small let's assume is less than 500 FPs, 2) rather static, where static doesn't mean like static HTML, but rather, a single purpose app that will undergo changes, but not be more than 1 or 2 things.... I DO expect lots of small tweaks, and in fact, that's why I'd pick PHP over Java since it's light and simple to change/hack 3) mostly UI, not much back end analytics or algorithmic code, and 4) interconnected to other web services and sites.

Oh sure, Java folks will beat me up, but I've earned my rank in Java and seen what it is good for and not, and still use it today. So let's not go there.

Your comments, data, facts, figures, observations are most welcome.

Thursday, July 05, 2007

Facebook App In Progress

Looking over the open source F8 app by NewsCloud. I may post a UML diagram if I have some time to kill, but essentially it breaks into these parts:

  1. init tasks
  2. Facebook input processing
  3. Response processing
Item 1 is accomplished through some very reasonable ctor code and PHP classes. (They seem to be using PHP4.) This pulls in their underlying libraries for SQL access, templating, formatting, etc. Don't know why they rolled their own in some cases (why not use Smarty for templates?)

Item 2 is stock F8 code, with some commercial-grade checking and error handling.

Item 3 is a big switch statement, keyed on the HTTP request input. The main cases correspond to pages: home, search, news, video, etc. Why they chose this over a true MVC framework is probably to simplify their life, since this is a relatively small app. Something like Cake or Symfony I am guessing would have been overkill. I like it; it's simple and clear and easy to understand, even if a bit hardcoded. Sometimes hardcoded is good. That's what they don't teach everyone ;)

What I really wanted to see was the fbml tags they were using, and how, and how they were formatting stuff. The tags they use are:
  • tabs
    • tab-item
  • message
  • notif-subject
  • iframe
  • req-choice
  • swf
  • friend-selector
  • share-button
  • userlink
  • wide
  • if-can-see
  • profile-pic
  • name
  • header
Their fbNewsCloud class has these methods, which essentially map to the anticipated use cases, and probably are good use cases for most F8 apps to consider:
  • buildNav - navigation dashboard div
  • buildStyles - adding CSS defs
  • buildSWF - for their video feeds
  • getNews/buildStoryLink - uses their templater class to build out the data from the DB...essentially this would be the heart of your service...getFoo()
  • getYourFriends - Got Viral? This is where you win big on the community angle - see what my friends are doing with this app
  • buildStory - Viral++ a bit of a misnomer, this builds the sharing link for the content...a must have for social capitalists
  • buildCommentThread - let yoru voice be heard, and those of others
  • getCloudList/fetchCloudStories - their concept of categories/groups
  • getClips/fetchClips/buildVideoLink - video clips
  • recordAction - keep a record of what the user is doing, a F8-ish concept as well as useful for mining
  • updateProfileBox/buildProfileBox/buildActionList/listActions - builds the fbml for the F8 profile widget; I would assume a necessary F8 component
  • getFriendsNews - related to the profile list, virulent strain
  • fetchSearchResults - search box
  • getWhatsHot - or not
  • friendsUsingApp/friendsNotUsingApp (and getInviteList/addToInviteList/updateLastInvite) - a.k.a. VP-Marketing-killer...why hire an MBA when the user can market your wares for you?
  • lookupFacebookUser - for invites
  • setInstalled/isAppInstalled - fql to see if we are installed
  • mapUser - they tie their users to F8 users; hmm OpenID anyone??
  • fetchAd - Aaah, need to pay the bills, eh?
  • buildGettingStarted/buildLeftIntro - the F8 add app call to action
  • setupTemplates - calls into the NC library of goodies and uses DB+minimal templates
Overall this leads to a good template for most F8 applications:
  1. Parse out the info sent back by Facebook
  2. template the responses
  3. separate logic from presentation code (MVC)
  4. follow key Facebook styles and concepts - dashboard, profile, friend list, etc.
Still, both the FBUtils.class and the NewsCloud.class don't really seem to be OO --- other than they encapsulate some values as members. If however, there was a base class for multiple social services, then having a polymorphic hierarchy might be useful.

In addition the the F8 logic, some controller code is required. NewsCloud puts this into a process.php file.

Now, to understand more about how to MARKET a F8 app once you've created it....that's for next time!

Wednesday, July 04, 2007

OnMyList List

Check it out:
OnMYList - My Save the Planet list

Congrats to Noah and the team for a decent UI and an addictive idea.

Thursday, June 21, 2007

PHP SYMFONY (a.k.a. Have you seen my CRUD?)

OK, so I looked at RoR and had some fun; now a headlong excursion into the YAML-y goodness of PHP Symfony. http://www.symfony-project.com

10:08 PM
Forgive me if I seem short tempered...I hurt my back this week, and it is excruciating. So I will tolerate very little from the gods of software in terms of framework lunacy. Either it works or it doesn't!

10:09 PM
Downloaded Symfony already ( http://www.symfony-project.com/get/symfony-stable.tgz ).
Then went to the My First App. RTFM? Ha!

10:10 PM
http://www.symfony-project.com/tutorial/my_first_project.html
OK, so I tried downloading the tgz. Uh, seems broken, guys. OK, well I'm sure my web sites have broken links. Fair enough.

10:11 PM
Found the sandbox on the download page. http://www.symfony-project.com/get/sf_sandbox.tgz

Unpacking....done. Gee, I hope it doesn't care that my Apache2 is in Program Files....spaces seem to stymie the open source folks. I guess that is for commercial apps only.

10:14 PM
http://localhost/sf_sandbox/web/index.php/
Great. Ugly URL, I guess they don't expect to use it for anything consumer oriented. OK, I won't rant on this again. Now what...reate a schema.yml file in sf_sandbox/config/ oh, YAML-icious!! Just what I need....ANOTHER way to screw up my app with an extra whitespace. Hooray! Thanks! Did I mention before that I was pre-Med in college? What was I thinking getting into software....

Anyhow...

10:17 PM
C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox>C:\php\p
hp.exe symfony propel-build-model
PHP Warning: PHP Startup: Unable to load dynamic library './php_pdo.dll' - The
specified module could not be found.
in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library './php_pdo_sqlite.dll'
- The specified module could not be found.
in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library './php_sqlite.dll' - T
he specified module could not be found.
in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library './php_xsl.dll' - The
specified module could not be found.
in Unknown on line 0

Yeah, I could have predicted that. OK, so maybe my PATH variable isn't set with c:\php correctly. fine fine fine!

10:25 PM
OK, well PHP's install set the wrong ext dir for Win32 (I know, I know....USE UNIX). OK, tangent here: I TRIED using SuSe Linux first! Apache wouldn't install! Ha! So, as much as I love *Nix and BSDs, sadly, if everything looks like a nail...

10:32 PM
Well, these Base* classes seem interesting. Guess it's time to look at exactly what propel is (I remember it when I looked at ORM for PHP awhile back, but for some reason long forgotten I opted for something else.)
http://propel.phpdb.org/trac/

All sounds good. One thing I always look at is the support mail lists. Hmmmm...all told, 5090 posts for Propel. Looking at Hibernate, just for fun, 132K! (And that's ignoring the German and Chinese user forums!) So, either Hibernate really sucks, and Propel is flawless...OR....well, if you want a job as a programmer, DON'T be a PHP (or Ruby or Python) developer. Java just has more jobs. (See related post on Java job counts.) And for those of you who, like me, use offshore engineers...don't even bother with PHP, Ruby, Python. Java may have its limitations, but 1B Chinese and Indian engineers can be a powerful reason to stay!

Of course, if reading my blog doesn't convince you that software engineering is a dead-end job, then I don't know how to help you. I guarantee, if I catch my daughtr within 30 feet of gcc, I'm taking away her stock options...and her pony!

10:43 PM
Back to Symfony.
propel-create-sql --- great. worked like a charm
propel-insert-sql next...

propel > insert-sql:
[propel-sql-exec] Executing statements in file: C:\Program Files\Apache Software
Foundation\Apache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql
[propel-sql-exec] Our new url -> sqlite://./../../../../data/sandbox.db
[propel-sql-exec] Executing file: C:\Program Files\Apache Software Foundation\Ap
ache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql
[propel-sql-exec] Failed to execute:

DROP TABLE [weblog_post]
[propel-sql-exec] Could not execute update [User Info:

DROP TABLE [weblog_post]]
[propel-sql-exec] Failed to execute:


DROP TABLE [weblog_comment]
[propel-sql-exec] Could not execute update [User Info:


DROP TABLE [weblog_comment]]
[propel-sql-exec] 2 of 4 SQL statements executed successfully

BUILD FINISHED

Total time: 1.0381 second
>> file- C:\Program Files\Apache Softwar...box\config\generated-schema.xml

HAHAHAAH. I guess I should have expected that! Well, my back is killing me so I don't have much patience for this now. I will pick this up in the AM when the Advil has done its job. For now, I leave you all with this thought: your finances are in the hands of software 'engineers' who aren't licensed or required to pass any competency review of any kind....good stuff, huh? Well, on that note, I shall ice may spine and drown my sorrows in Isle of Jura. Oh I highly recommend it! TTFN!

NEXT DAY:

1:21 PM
After a fun morning of business, it's time to get down to this PHP business.
Rather than focusing on getting sqllite working, since I am actually interested in prototyping something real, I will try switching to MySQL which is what I will use for my real application, at least as a prototype. This is the last chance, Symfony, else I switch back to Ruby on Rails.

1:23 PM
http://www.symfony-project.com/book/trunk/08-Inside-the-Model-Layer#Database%20Connections

1:40
Getting an error on MySQL:
propel > insert-sql:
[propel-sql-exec] Executing statements in file: C:\Program Files\Apache Software
Foundation\Apache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql
[propel-sql-exec] Our new url -> mysql://foo:bar@localhost/sandbox
Execution of target "insert-sql" failed for the following reason: C:\Program Fil
es\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\lib\symfony\vendor\pro
pel-generator\build-propel.xml:296:1: [wrapped: connect failed [Native Error: C
an\'t connect to MySQL server on \'localhost\' (10061)] [User Info: Array]]
[phing] C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sand
box\lib\symfony\vendor\propel-generator\build-propel.xml:296:1: [wrapped: conne
ct failed [Native Error: Can\'t connect to MySQL server on \'localhost\' (10061)
] [User Info: Array]]

BUILD FINISHED

Let me try a simple PHP->MySql on this box, since I haven't done so before (clean install).
.........................................................................
.........................................................................
LATER THAT DAY.......................................

Well, after considerable debugging, including attaching VS to the apache httpd process just to make sure all the right DLLs were getting loaded (no ldd or truss on Win32, although Depends.exe comes in handy in such cases)....I was able to deduce (OK, actualy powers of deduction would have landed me here 4 hours ago...) that my MySQL was running on a non-standard port 3333 for some inane reason. After reading all the posts, and trying untold different experiments, I was able to connect. The trigger? I used a different client tool, Heidi SQL, which failed to connect!! So the cmd line mysql has cached the port. Once Heidi failed, I netstat'd and lo and behold, the solution. Although even after that, I almost shot myself in the foot, cause I was using some bad mysql syntax...unfortunately, PHP didn't give me helpful error messages, so I almost concluded that the port was not the issue, or at least not the only issue. But in the end, I won (if you can call wasting the better part of a beautiful day banging your head against Google "winning"). Med school is looking pretty fun right now...even proctology!

Just FYI - here's my PHP hellow world code that I used to verify basics:

";

// Show all information, defaults to INFO_ALL
phpinfo();

$database = "mysql";

$link = mysqli_connect("localhost", "xxxxx", "yyyyyyy", $database, 3333);

/* check connection */
if (!$link) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}


echo "
    ";
    echo "
  • ".$database;

    // for each database, get table list and print
    $query2 = "SHOW TABLES FROM ".$database;
    $result2 = mysqli_query($link, $query2) or die ("Error in query: $query2. ".mysqli_error());

    echo "
      ";
      while ($row2 = mysqli_fetch_array($result2)) {
      echo "
    • ".$row2[0];
      }
      echo "
    ";

    echo "
";

mysqli_close();

?>

But I digress...onwards and upwards!

10:47 PM (yep, really...ok I had breaks for dinner and story time for the daughter)
Now I can at least, readlly get back to where we were just about 24 hours ago.

propel > insert-sql:[propel-sql-exec] Executing statements in file: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql[propel-sql-exec] Our new url -> mysql://xxxx:yyyyyy@localhost/sandboxExecution of target "insert-sql" failed for the following reason: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\lib\symfony\vendor\propel-generator\build-propel.xml:296:1: [wrapped: mysql extension not loaded [User Info: Array]] [phing] C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\lib\symfony\vendor\propel-generator\build-propel.xml:296:1: [wrapped: mysql extension not loaded [User Info: Array]]

OK, well this is true, I enabled mysqli, cause that's what the manual said to!! So, I can enable both (I hope)...

10:52 PM
propel > insert-sql:[propel-sql-exec] Executing statements in file: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql[propel-sql-exec] Our new url -> mysql://xxxxx:yyyyy@localhost/sandbox[propel-sql-exec] Executing file: C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox\data\sql\lib.model.schema.sql[propel-sql-exec] 6 of 6 SQL statements executed successfully

HOLY GUACAMOLE! And even my hello world (changed the $database="sandbox"):
sandbox
weblog_comment
weblog_post

well. About time!

10:55PM
C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox>php symfony propel-generate-crud frontend post Post>> dir+ C:\Program Files\Apache Softwar...s/frontend/modules/post\actions>> file+ C:\Program Files\Apache Softwar.../post\actions\actions.class.php>> dir+ C:\Program Files\Apache Softwar...frontend/modules/post\templates>> file+ C:\Program Files\Apache Softwar.../post\templates\editSuccess.php>> file+ C:\Program Files\Apache Softwar.../post\templates\listSuccess.php>> file+ C:\Program Files\Apache Softwar.../post\templates\showSuccess.php>> tokens C:\Program Files\Apache Softwar.../post/actions/actions.class.php>> tokens C:\Program Files\Apache Softwar.../post\actions\actions.class.php>> tokens C:\Program Files\Apache Softwar.../post\templates\editSuccess.php>> tokens C:\Program Files\Apache Softwar.../post\templates\listSuccess.php>> tokens C:\Program Files\Apache Softwar.../post\templates\showSuccess.php>> file+ C:\Program Files\Apache Softwar...al/frontend/postActionsTest.php>> tokens C:\Program Files\Apache Softwar...al/frontend\postActionsTest.php>> file- C:\Program Files\Apache Softwar...oPost\templates\showSuccess.php>> file- C:\Program Files\Apache Softwar...oPost\templates\listSuccess.php>> file- C:\Program Files\Apache Softwar...oPost\templates\editSuccess.php>> dir- C:\Program Files\Apache Softwar...293669c9388e\autoPost\templates>> file- C:\Program Files\Apache Softwar...oPost\actions\actions.class.php>> dir- C:\Program Files\Apache Softwar...68293669c9388e\autoPost\actions>> dir- C:\Program Files\Apache Softwar...73dc2a7d68293669c9388e\autoPost

C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox>php symfony propel-generate-crud frontend comment Comment>> dir+ C:\Program Files\Apache Softwar...rontend/modules/comment\actions>> file+ C:\Program Files\Apache Softwar...mment\actions\actions.class.php>> dir+ C:\Program Files\Apache Softwar...ntend/modules/comment\templates>> file+ C:\Program Files\Apache Softwar...mment\templates\editSuccess.php>> file+ C:\Program Files\Apache Softwar...mment\templates\listSuccess.php>> file+ C:\Program Files\Apache Softwar...mment\templates\showSuccess.php>> tokens C:\Program Files\Apache Softwar...mment/actions/actions.class.php>> tokens C:\Program Files\Apache Softwar...mment\actions\actions.class.php>> tokens C:\Program Files\Apache Softwar...mment\templates\editSuccess.php>> tokens C:\Program Files\Apache Softwar...mment\templates\listSuccess.php>> tokens C:\Program Files\Apache Softwar...mment\templates\showSuccess.php>> file+ C:\Program Files\Apache Softwar...frontend/commentActionsTest.php>> tokens C:\Program Files\Apache Softwar...frontend\commentActionsTest.php>> file- C:\Program Files\Apache Softwar...mment\templates\showSuccess.php>> file- C:\Program Files\Apache Softwar...mment\templates\listSuccess.php>> file- C:\Program Files\Apache Softwar...mment\templates\editSuccess.php>> dir- C:\Program Files\Apache Softwar...5913509f4\autoComment\templates>> file- C:\Program Files\Apache Softwar...mment\actions\actions.class.php>> dir- C:\Program Files\Apache Softwar...4a5913509f4\autoComment\actions>> dir- C:\Program Files\Apache Softwar...2bad135b4a5913509f4\autoComment

C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\sf_sandbox>php symfony clear-cache>> file+ C:\Program Files\Apache Softwar...cs\sf_sandbox/frontend_prod.lck>> chmod 777 C:\Program Files\Apache Softwar...cs\sf_sandbox\frontend_prod.lck>> file- C:\Program Files\Apache Softwar...he\frontend\prod\config\VERSION>> file- C:\Program Files\Apache Softwar...les_default_config_view.yml.php>> file- C:\Program Files\Apache Softwar...default_config_security.yml.php>> file- C:\Program Files\Apache Softwar...s_default_config_module.yml.php>> file- C:\Program Files\Apache Softwar...efault_config_generator.yml.php>> file- C:\Program Files\Apache Softwar..._default_config_filters.yml.php>> file- C:\Program Files\Apache Softwar...\config\config_settings.yml.php>> file- C:\Program Files\Apache Softwar...d\config\config_routing.yml.php>> file- C:\Program Files\Apache Softwar...\prod\config\config_php.yml.php>> file- C:\Program Files\Apache Softwar...d\config\config_logging.yml.php>> file- C:\Program Files\Apache Softwar...prod\config\config_i18n.yml.php>> file- C:\Program Files\Apache Softwar...config\config_factories.yml.php>> file- C:\Program Files\Apache Softwar...config\config_databases.yml.php>> file- C:\Program Files\Apache Softwar...fig\config_core_compile.yml.php>> file- C:\Program Files\Apache Softwar...\config_config_handlers.yml.php>> file- C:\Program Files\Apache Softwar...onfig_bootstrap_compile.yml.php>> file- C:\Program Files\Apache Softwar...\config\config_autoload.yml.php>> file- C:\Program Files\Apache Softwar...\prod\config\config_app.yml.php>> file- C:\Program Files\Apache Softwar...cs\sf_sandbox/frontend_prod.lck

Seems OK....I guess. Would be nice to know what all that is doing, so I'll want to take a deeper look (after med school). OK, well, of couse something will break and I'll have to look at it sooner than that.

10:58PM
Well, just about 24 hours later, and much scotch, and a bad back to boot...we finally have our CRUD. I am definitely changing careers. This is lunacy. Well, I'm off to make some tea and refresh myself on Organic Chemistry...SN2 baby! It's all about SN2!

Ciao! Zai Jian!

In Memoriam

Julia T. Ficcaglia passed away peacefully in her sleep at age 92 during the early morning hours of Tuesday, June 5, 2007 from complications brought about by severely advanced arthritis. Julia was born in Far Hills, New Jersey on September 19, 1914 and came to Phoenix in late December 1942 to marry Raymond Ficcaglia at what is now St. Mary's Basilica in downtown Phoenix on December 31, 1942 and remained a resident of Arizona through her passing. Julia is survived by her younger sister, Mary McGowan in New Jersey, her twin sons, 5 grandsons, one great grandson and one great granddaughter, Julia Ruth Ficcaglia. Julia was a charter member of the Ladies Sodality at St. Thomas the Apostle Catholic Church, 2312 E. Campbell Ave. in Phoenix, where her Funeral Mass will be celebrated Friday morning, June 15, 2007 at 10:00 A.M. Visitation will be held the evening before at Whitney & Murphy Funeral Home, 4800 E. Indian School Rd., from 6:00 - 8:00 P.M. with Scripture Service at 7:00 P.M. Julia will be interred with her husband at St. Francis Catholic Cemetery in Phoenix following the Mass. Donations may be made to the Arthritis Foundation, 1313 E. Osborn Rd. #200, Phoenix, AZ 85014 in her name in lieu of flowers.
Published in The Arizona Republic on 6/13/2007.

There is much more to her story than this brief epilogue. Hers was one of the world's purest love stories, as she waited faithfully for over 30 years after the death of her one and only love. We can now comfort ourselves with the notion that now, finally, Julia and her Raymond are once again reunited in some unknown dimension. Perhaps Feynman would concur that Love is the strangest force of Nature, a timeless energy inscrutable by scientific inquiry. Let us all hope we can experience an energy that clean and pure in our own lives.

We will miss you Grandma Julie!

Monday, February 19, 2007

Some Family History

Recently stumbled upon:

Ficcaglia, Mariantonia
Female
census date 1/10/1824

Parents:
Fater - Ficcaglia, Errico
Mother - Aspromonte, Maria
Paternal gradfather - Ficcaglia, Domenico
father's occupation - water-man (probably a river boat captain!)
Record Number: 5

Piccirelli, Mariantonia b. ABT 1779 Family:
Marriage: ABT 1799Spouse: Ficcaglia, Domenico b. ABT 1770
Children:
Ficcaglia, Enrico
Testa, Domenicantonio b. ABT 1700 Palena, Chieti, Italy
Family:
Marriage: ABT 1811 Palena, Chieti, Italy
Spouse: Ficcaglia, Rachela b. ABT 1788 Palena, Chieti, Italy
Children:
Testa, Pietro Maria b. 29 Apr 1812 Palena, Chieti, ItalyTesta, Erminto Giuseppe Maria b. 28 May 1824 Palena, Chieti, ItalyTesta, Giuseppe Maria b. 25 Jan 1827 Palena, Chieti, ItalyTesta, Michele Arcangelo Maria b. 31 Jan 1829 Palena, Chieti, Italy


Ficcaglia, Giustino
Male
5/19/1829
Birth

PArents:
Ficcaglia, Errico (father)
Aspromonte, Maria (mother)
Ficcaglia, Domenico (paternal grandfather)
Aspromonte, Donato (maternal gf)

proprietor (father's occupation)
73



Teti, Mariantonia
F
11/15/1829
Birth
Teti, Domenico
Ficcaglia, Felice
Teti, Francesco

Note--Listed as Mariantonia Ficcaglia in baptism portion of birth record, but as Mariantonia Teti in index.
dyer
121
Since I have never met a Ficcaglia I wasn't related to, I assume these are famiglia!