Friday, March 31, 2006

os x

http://wiki.onmac.net/index.php/HOWTO <-- installing XP on an iMac is possible after all. "What You'll Need

* An original XP PRO SP2 CDROM (It doesn't have to be bootable, but it should have a i386 directory in the root.) "




http://www.reghardware.co.uk/2006/03/22/mac_fastest_core_duo_laptop/

intel MacBook is the fastest Windows XP notebook.

"Want the fastest Windows XP Core Duo notebook? Then buy a Mac. According to benchmarks carried out by website GearLog, Apple's MacBook Pro running Windows XP is a better Adobe Photoshop rig than any other Core Duo laptop on the market."

booting xp on intel mac is possible after all

in the past they said that windows xp installer won't boot on an intel mac 'coz it is dependent on BIOS while intel mac doesn't use BIOS, it uses EFI instead.

now things gone full circle, you can now install xp on an intel mac, somebody had hack an EFI bootloader for windows xp cd installer

get the bootloader here
http://download.onmac.net/


http://wiki.onmac.net/index.php/HOWTO

What You'll Need
  • An original XP PRO SP2 CDROM (It doesn't have to be bootable, but it should have a i386 directory in the root.)
  • The winxponmac0.1.zip file
  • A PC with XP already installed (To do this without a PC with XP installed see section 2.4)
  • Nero Burning ROM
  • A blank CD (Preferrably a CD-RW, just in case it doesn't work first time)
  • 20–30 minutes



----------


http://www.apcmag.com/apc/v3.nsf/0/64E7EA353646669ECA2570F50012430B

Tech journos far and wide have been quick to jump on the story that while Apple says it isn’t doing anything to specifically prevent people from installing Windows on an Intel-based Mac, the new Extensible Firmware Interface (EFI) that Apple is using on the new Macs won’t work with current generations of Windows.

EFI is the next-generation replacement for the 20-year-old BIOS, the oldest part of modern PCs which is in desperate need of an overhaul. EFI allows devices in the PC to be initialised before the operating system boots, and has features like full network support before the PC has even booted, allowing drivers to be downloaded and updated before an operating system loads.

Thursday, March 30, 2006

Static in the Call Center - ESD Journal: "In normal office chairs, when a person sits in and scoots around in the chair then stands up, they accumulate a significant electrostatic charge which may then discharge through the telephone headset or to another worker"

Static shocks and how to avoid them: "Why do I get shocks when I touch the door knob or filing cabinet?
Most modern shoes have highly insulating rubber or plastic soles. As you walk, static charges can build up on the soles of the shoes. This is especially true if the floor is also insulating. Some older nylon carpets are particularly good at generating static electricity.
The charge on the shoes soles induces static electrical charge on your body, and this charge appears as a high voltage. Under severe conditions, more than 15,000 Volts have been recorded. It is quite common to experience 5,000V. In fact, many people do not feel a shock from a static electricity discharge less than about 2,000-4,000V.
If you are indoors, the point can be proved by walking around for a while with no shoes on - you will probably not experience shock."

Wednesday, March 29, 2006

vbAccelerator - Compact a Long Path Name to fit a given space:

Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hDC As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Private Const DT_BOTTOM = &H8&
Private Const DT_CENTER = &H1&
Private Const DT_LEFT = &H0&
Private Const DT_CALCRECT = &H400&
Private Const DT_WORDBREAK = &H10&
Private Const DT_VCENTER = &H4&
Private Const DT_TOP = &H0&
Private Const DT_TABSTOP = &H80&
Private Const DT_SINGLELINE = &H20&
Private Const DT_RIGHT = &H2&
Private Const DT_NOCLIP = &H100&
Private Const DT_INTERNAL = &H1000&
Private Const DT_EXTERNALLEADING = &H200&
Private Const DT_EXPANDTABS = &H40&
Private Const DT_CHARSTREAM = 4&
Private Const DT_NOPREFIX = &H800&
Private Const DT_EDITCONTROL = &H2000&
Private Const DT_PATH_ELLIPSIS = &H4000&
Private Const DT_END_ELLIPSIS = &H8000&
Private Const DT_MODIFYSTRING = &H10000
Private Const DT_RTLREADING = &H20000
Private Const DT_WORD_ELLIPSIS = &H40000

Private Declare Function PathCompactPath Lib "shlwapi" Alias "PathCompactPathA" ( _
ByVal hDC As Long, ByVal lpszPath As String, ByVal dx As Long) As Long

Public Function CompactedPath( _
ByVal sPath As String, _
ByVal lMaxPixels As Long, _
ByVal hDC As Long _
) As String
Dim tR As RECT
tR.right = lMaxPixels
DrawText hDC, sPath, -1, tR, DT_PATH_ELLIPSIS Or DT_SINGLELINE Or DT_MODIFYSTRING
CompactedPath = sPath
End Function

Public Function CompactedPathSh( _
ByVal sPath As String, _
ByVal lMaxPixels As Long, _
ByVal hDC As Long _
) As String
Dim lR As Long
Dim iPos As Long
lR = PathCompactPath(hDC, sPath, lMaxPixels)
iPos = InStr(sPath, Chr$(0))
If iPos <> 0 Then
CompactedPathSh = left$(sPath, iPos - 1)
Else
CompactedPathSh = sPath
End If
End Function

To try out the code, add a command button to your test project's main form. Then add two label controls to the form, sizing the second one to the size you'd like the path to appear as. Type an obnoxiously long path containing spaces into the caption of the first label control, for example:

C:\Program Files\Microsoft DevStudio\Visual Basic\Samples\Unsupported Samples\Etc

Then add the following code to demonstrate the path compacting:

Private Sub Command1_Click()
' Use either the CompactedPath or CompactedPathSh functions - they
' work exactly the same.
Label2.Caption = CompactedPathSh( _
Label1.Caption, Label2.Width \ Screen.TwipsPerPixelX, Me.hDC)
End Sub

search urls

miblogic: http://www.villman.com/products/search.asp?T1=%s&image1.x=0&image1.y=0
miblogic: http://www.thefreedictionary.com/dict.asp?Word=%s
miblogic: http://www.pcx.com.ph/search/default.asp?q=%s&Search.x=0&Search.y=0
miblogic: http://search.msdn.microsoft.com/search/results.aspx?view=msdn&qu=%s
miblogic: http://www.thefreedictionary.com/dict.asp?Word=%s
miblogic: http://en.wikipedia.org/wiki/Special:Search?search=%s&fulltext=Search

sql server 2005: out-of-the-box support for recursive query

http://www.sqlservercentral.com/columnists/sSampath/recursivequeriesinsqlserver2005.asp

Recursive Queries

Having seen the basic syntax of a CTE and some its use cases in my last article, let us turn to the more interesting use: Recursive Queries. A recursive query is one in which a CTE references itself. What is the use of a recursive query? Well, all of us SQL Server 2000 users have always wanted to build hierarchical data. The most classical example is when you are given an organization structure and you wanted to represent the same in a relational database and run queries against it.

In SQL Server 2000, there was no inherent way to perform hierarchical queries and people had different implementations. You can get dozens of them if you search GOOGLE. The SQL Server 2000 Books Online also had a topic called Expanding Hierarchies where a sample implementation was provided. With the advent of recursive queries however, we now have a standard implementation for working with hierarchical data and querying against it.

When you are using a recursive CTE, the syntax of the CTE changes slightly as shown:

WITH cte_name (optional column list) AS
(
Cte_query_1
UNION ALL
Cte_query_2
)
Statement that uses the above CTE
OPTION (MAXRECURSION n)

First of all, note that a recursive query is made up of 2 queries joined by a UNION ALL. The first query is called the anchor member and it forms the basic result set. The second query is called the recursive member and this is where the CTE references itself. The recursive member forms the next part of the result set using the anchor member as input. The recursive member is called repeatedly until no more rows are returned (called the exit condition). Here are some quick rules about the recursive member.

Only UNION ALL is allowed between the anchor and the recursive member
Only 1 CTE reference per recursive member is allowed
When I first read about CTEs, my thought was: Hey, this is similar to how I would write a recursive factorial program! You could not be far away from the truth and in fact, it makes a lot of sense to understand CTEs from the point of how we write recursive functions in programming languages. Here is an implementation of a recursive factorial program using VB.NET.

Module Module1
Sub Main()

Dim result As Integer
Dim number As Integer

number = 5
result = number
result = number * Factorial(number - 1)
Console.WriteLine("{0}", result)
Console.ReadLine()

End Sub

Private Function Factorial(ByVal number As Integer) As Integer

Dim result As Integer

If (number = 0) Then
Return (1)
End
If result = number * Factorial(number - 1)
Return (result)

End Function

End Module

Let’s dissect the above program and equate it to terms that we introduced in the recursive CTE definition.

At the start of the program, we assign the input value to “result”. This is the anchor member and establishes the starting point.
After this, we call the “Factorial” function in a recursive fashion by passing in values decremented by 1 by each call. This is similar to the recursive member starting off from the anchor.
In the function, we have a check to see if the incoming parameter is 0 and if so, we return a value of 1. This indicates that we have reached the end of the recursion and the condition is similar to the exit condition.
When the exit condition is reached, the stack is unwound and the values are assigned to the “result” variable and finally returned where it is combined with the anchor and the final result (120 in our example) is displayed.
Ok, having seen the basics of a recursive query, let’s turn to some real-world problems with respect to that. For the sake of understanding how recursive queries work, let us consider the case of an organizational hierarchy and the different types of queries that we want to fire against it.

Here is the sample organizational chart.

Chief Executive Officer
Senior Director – Product Development
Product Development Manager
Project Lead
Developers
QA Lead
Testing Team
Documentation Lead
Technical Writers
Senior Director – Finance
Accountants
Senior Director – Human Resources
HR Professionals
Note that we are representing only the structure and not the people playing the roles. For example, there may be many project leads under a single product development manager, but we are interested in only the structure of the organization and not how many people of each type are present.

Let us now create the table to hold this structure and then populate it with data. Here are the sample scripts that I’ve used.

IF (OBJECT_ID ('dbo.SampleOrg', 'U') IS NOT NULL)
DROP TABLE dbo.SampleOrg
GO
CREATE TABLE dbo.SampleOrg
(
LevelID INT NOT NULL PRIMARY KEY,
Position NVARCHAR(50) NOT NULL,
ReportingLevelID INT REFERENCES dbo.SampleOrg (LevelID)
)
GO
-- Insert some sample data into the table based on the structure
-- shown above
INSERT INTO dbo.SampleOrg SELECT 1, 'Chief Executive Officer', NULL
INSERT INTO dbo.SampleOrg SELECT 2, 'Senior Director - Development', 1
INSERT INTO dbo.SampleOrg SELECT 3, 'Senior Director - Finance', 1
INSERT INTO dbo.SampleOrg SELECT 4, 'Senior Director - Human Resources', 1
INSERT INTO dbo.SampleOrg SELECT 5, 'Product Development Manager', 2
INSERT INTO dbo.SampleOrg SELECT 6, 'Project Lead', 5
INSERT INTO dbo.SampleOrg SELECT 7, 'QA Lead', 5
INSERT INTO dbo.SampleOrg SELECT 8, 'Documentation Lead', 5
INSERT INTO dbo.SampleOrg SELECT 9, 'Developers', 6
INSERT INTO dbo.SampleOrg SELECT 10, 'Testers', 7
INSERT INTO dbo.SampleOrg SELECT 11, 'Writers', 8
INSERT INTO dbo.SampleOrg SELECT 12, 'Accountants', 3
INSERT INTO dbo.SampleOrg SELECT 13, 'HR Professionals', 4
GO

Ok. Now that we have the sample data in place, let us try some recursive queries to see how they work.

Sample 1: Show the levels that directly report to the Product Development Manager

Before we dissect the logic used to achieve this requirement, let us see the query itself. Here is the snippet that produces the above requirement based on the organization chart table created earlier.

WITH SampleOrgChart (Level, Position, ReportingLevel, OrgLevel, SortKey) AS
(
-- Create the anchor query. This establishes the starting
-- point
SELECT
a.LevelID, a.Position, a.ReportingLevelID, 0,
CAST (a.LevelID AS VARBINARY(900))
FROM dbo.SampleOrg a
WHERE a.Position = 'Product Development Manager'
UNION ALL
-- Create the recursive query. This query will be executed
-- until it returns no more rows
SELECT
a.LevelID, a.Position, a.ReportingLevelID, b.OrgLevel+1,
CAST (b.SortKey + CAST (a.LevelID AS BINARY(4)) AS VARBINARY(900))
FROM dbo.SampleOrg a
INNER JOIN SampleOrgChart b ON a.ReportingLevelID = b.Level
WHERE b.OrgLevel < 1
)
SELECT * FROM SampleOrgChart ORDER BY SortKey

Let’s understand what this query does:

First, we create the anchor member as the record which is for the Product Development Manager. As part of this query, we create two pseudo columns. One for indicating the level (called OrgLevel) and for sorting the records in the right fashion (called SortKey). The sort key for us is the primary key of the table converted to a binary column.
After the anchor query, we now use this as the input and form the recursive query. Note that the recursive query increments the OrgLevel column and also builds the SortKey column.
Since we want only the people who directly report to the product development manager, we specify the condition OrgLevel < 1. What happens if we omit this condition? That is the next sample…
Sample 2: Show all the levels that report to the Product Development Manager

Here is the query that provides all the levels that reports to the product development manager.

WITH SampleOrgChart (Level, Position, ReportingLevel, OrgLevel, SortKey) AS
(
-- Create the anchor query. This establishes the starting
-- point
SELECT
a.LevelID, a.Position, a.ReportingLevelID, 0,
CAST(a.LevelID AS VARBINARY(900))
FROM dbo.SampleOrg a
WHERE a.Position = 'Product Development Manager'
UNION ALL
-- Create the recursive query. This query will be executed
-- until it returns no more rows
SELECT
a.LevelID, a.Position, a.ReportingLevelID, b.OrgLevel+1,
CAST(b.SortKey + CAST (a.LevelID AS BINARY(4)) AS VARBINARY(900))
FROM dbo.SampleOrg a
INNER JOIN SampleOrgChart b ON a.ReportingLevelID = b.Level
)
SELECT * FROM SampleOrgChart ORDER BY SortKey

Note that by removing the WHERE clause in the recursive query, we keep going down the hierarchy.

OK, by now, you will have a fair understanding of the power that CTEs and Recursive Queries put in your hands. I can keep writing about many situations possible, but there is a space and word constraint as far as a technical article goes!

As an exercise to the readers, see if you can write a query that displays the organization chart (basically all the above examples, display the records, but not like a chart). That should keep you going and enjoying this feature.

Monday, March 27, 2006

How to solve Suspect Database - ITtoolbox Groups:

"EXEC sp_dboption 'mydatabase', 'single user', 'TRUE'

to restore multi user

EXEC sp_dboption 'mydatabase', 'single user', 'off'

to restore multi user

"

Wednesday, March 22, 2006

vbCity/DevCity.NET Forums :: Visual Basic :: VB Controls & ActiveX :: ToolBoxBitmap: "Hard job

The toolboxbitmap is strored in the ocx as a ressource as a Bitmap. you can retrieve the Id in the registry under the ClsId of the ocx at the Key ToolBoxBitmap32

So you must first retreive the clsId, then look in the registry for the toolboxbitmap32 Id, then load the ocx with the function LoadLibrary, find the ressource as a byte array, save the array as file , unload the library and then you can use loadpicture to retrieve it

Good Luck
"

vbCity/DevCity.NET Forums :: Visual Basic :: VB Controls & ActiveX :: ToolBoxBitmap: "So here's my situation...I've been faced with the task of creating Visual Basic from within Visual Basic...I have been working on the designer (where you place controls and move them around etc) and i can dynamically create controls and add scripting to them, but what I'm stuck on is kind of embarassing...

I want to know how to get the bitmaps out of the controls (i want to display each available control just the way VB does it in the toolbox). See my attachment for more info on what i'm talking about

Right now i am creating a bunch of small command buttons and setting their tooltip's to their corresponding ProgID's to tell them apart, but i'd like to be able to access the 'ToolBoxBitmap' property of a control to get the image to display on each tiny comand button.

Any ideas? Hints?

Thanks in advance!!
"

implementing strikethrough in datawidget

pag ni-type yung styleset.font.strikethrough, hindi automatic na nalabas sa intellisense yung mga properties(underline, italic, strikethrough, etc) nung font nung styleset ng infragistic grid. para mapalabas yung mga properties nung font nung infragistic styleset, i-assign sa Font object yung .Font nung styleset. then pwedeng sa Font variable na i-set yung mga font's property like underline, italic, strikethrough, bold, etc

------------

Option Explicit

Private Sub Form_Load()
Dim s As StyleSet

grd.StyleSets.Add "Failed"
Set s = grd.StyleSets("Failed")
'Dim f As Font
'Set f = s.Font
s.Font.Strikethrough = True ' line 7
s.Font.Name = "Comic Sans MS"
' mas better, itong sa baba, automatic nalabas yung intellisense, i-uncomment lang yung Dim f and Set f sa taas, then comment the line 7, uncomment line 8
'f.Strikethrough = True ' line 8


End Sub

Private Sub grd_RowLoaded(ByVal Bookmark As Variant)

If grd.Columns("Grade").CellValue(Bookmark) > 3 Then

grd.Columns("Subject").CellStyleSet "Failed"

Else
grd.Columns("Subject").CellStyleSet ""
End If

End Sub

CodeGuru: Rotate a Bitmap at Any Angle Without GetPixel/SetPixel:

Using GetDIBits

This code is much faster because it uses GetDIBits to get the 32-bit representation of the bitmap to rotate. All operations are done in local memory rather than in slow API calls such as GetPixel or even BitBlt. I use the 32-bit representation mainly for its ease of use. When working with other color depths, you have to add some padding bytes at the end of each scan line, which is not necessary in 32 bits. Moreover, it allows easier access to the memory.

pBGR MyGetDibBits(HDC hdcSrc, HBITMAP hBmpSrc, int nx, int ny)
{
BITMAPINFO bi;
BOOL bRes;
pBGR buf;

bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = nx;
bi.bmiHeader.biHeight = - ny;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = nx * 4 * ny;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;

buf = (pBGR) malloc(nx * 4 * ny);
bRes = GetDIBits(hdcSrc, hBmpSrc, 0, ny, buf, &bi,
DIB_RGB_COLORS);
if (!bRes) {
free(buf);
buf = 0;
}
return buf;
}

RotateMemoryDC

This function does all the work. Apart from getting the source coordinate from a target coordinate, it is very straightforward. The formulas I use are these:
orgX = (cA * (((float) stepX + OfX) + CtX * (cA - 1)) + sA * (((float) stepY + OfY) + CtY * (sA - 1))) / cA*cA + sA*sA;

orgY = CtY + (CtX - ((float) stepX + OfX)) * sA + cA *(((float) stepY + OfY) - CtY + (CtY - CtX) * sA);

cA is just cos(angle) and sA is sin(angle). CtX and CtY are the center of the source image and OfX and OfY are the offsets of the source image inside the target image. This is necessary because the target image has to be bigger than the source.

I actually make a point of using floating point operations in the inner loop to show that the performance does not depend on these. In the old days of DOS, when PCs were slow at floating point operations and graphics manipulation was fast because it consisted only of accessing a special part of the system memory, the bottleneck was indeed the floating point operations. With GDI, this is unfortunately not true anymore. Most of the time is taken up by getting the bitmaps and setting them.

Changing the calculations to fixed point math will only result in a marginal improvement in the overall speed.
General Notes

The program is based on the sample "Hello World" application generated by Visual C++ 6. I just added the new drawing code and a Timer so that the bitmap rotates continuously.

Tuesday, March 21, 2006

.NET 247 : Where have PSet and Point gone? on microsoft.public.dotnet.languages.vb.upgrade: "I was a little to quick with the typing there. . . . The second line should
be:

CType(Pic1.Image, Bitmap).SetPixel(10, 20, Color.White)
"

image fix dimension

Set im.Picture = LoadPicture("D:\_MIKE_DOCUMENT_\My Pictures\no-strings-attached.bmp")
'Set ImgXCtrl1.Picture = LoadPicture("D:\_MIKE_DOCUMENT_\My Pictures\cebo.jpg")
'Set ImgXCtrl1.Picture = LoadPicture("D:\_MIKE_DOCUMENT_\My Pictures\adidas.jpg")
'Set ImgXCtrl1.Picture = LoadPicture("D:\_MIKE_DOCUMENT_\My Pictures\nike.jpg")



MsgBox ""

Dim ObtainPercentX As Double
Dim ObtainPercentY As Double


Dim FixDimension As Integer

FixDimension = 200

im.Move im.Left, im.Top, FixDimension * Screen.TwipsPerPixelX, FixDimension * Screen.TwipsPerPixelY


If im.Image.Width > FixDimension Or im.Image.Height > FixDimension Then


Dim AspectRatio As Double

If im.Image.Width > im.Image.Height Then

AspectRatio = FixDimension / im.Image.Width

im.Effects.Resize FixDimension, AspectRatio * im.Image.Height




Else

AspectRatio = FixDimension / im.Image.Height



im.Effects.Resize AspectRatio * im.Image.Width, FixDimension




End If

End If


Mga Grupo sa Google : microsoft.public.dotnet.general: "I don't think it is lack of smartness on the part of the compiler that is
the problem. The compiler is being quite smart enough when it declares that
you cannot set a fruit to an int. The fact that a fruit is represented
internally by an int is purely incidental. Externally, fruit is a set which
contains apple, orange, pear, etc. Unless you tell the compiler, explicitly,
that it can interpret 4 as a fruit then it should quite rightly get upset. "

Sunday, March 19, 2006

adam machanic :: data manipulation for fun and profit : Running sums, redux: "So what have we learned today? In my set-based singlemindedness I failed to realize that the cursor does, indeed, have utility. Everything in moderation."


Running sums, redux
Siddhartha Gautama, the Buddha, taught us to understand that the key to enlightenment is following the Middle Path. And today I learned a valuable lesson in extremes. You can file this one in the "Doh! Wrong again!" category...

A fairly common question on SQL Server forums is, "how can I get the running sum of the data in this column?" Being the fan of set-based queries that I am, I always answer the exact same way. I show the person asking the question how to do a self-join on the grouped column, getting all of the "previous" values to create a running sum. The following example shows how you might do this against the AdventureWorks Production.TransactionHistory table:


SELECT
TH1.TransactionID,
TH1.ActualCost,
SUM(TH2.ActualCost) AS RunningTotal
FROM Production.TransactionHistory TH1
JOIN Production.TransactionHistory TH2 ON TH2.TransactionID <= TH1.TransactionID
GROUP BY TH1.TransactionID, TH1.ActualCost
ORDER BY TH1.TransactionID


Pretty simple query. For each row of the "TH1" alias, every row with a lesser-or-equal TransactionID will be summed. Thereby creating a running total for every row of the table. Note, I've used the IDENTITY column instead of the date column. I'd generally suggest not doing so because, e.g., you might need to insert some post-dated rows at some point and relying on the IDENTITY for a time sequence will thereby not work. But in this case it's a lazy solution because the TransactionDate column isn't indexed, and it's also not unique. I want to test a lot of rows (TransactionHistory has around 113,000), but I don't want to skew the test by forcing a table scan on every iteration!

But I digress. The point is, I've given this answer more than a few times and, well, I'd like to apologize. Just now I went ahead and ran this query on my powerful test server--err, my laptop.

As you might guess, since I'm performance-minded I also happen to be extremely impatient--so I went ahead and killed the query at the five-minute mark. SSMS's result grid showed the first 26,568 rows, so obviously there was a long way to go to hit that 113,000 mark. And with an estimated cost of 38,086 for the query, I can't say I'm surprised.

A few moments of head scratching and the following re-write was issued:


SELECT
TH1.TransactionID,
TH1.ActualCost,
(
SELECT SUM(TH2.ActualCost)
FROM Production.TransactionHistory TH2
WHERE TH2.TransactionID <= TH1.TransactionID
) AS RunningTotal
FROM Production.TransactionHistory TH1
ORDER BY TH1.TransactionID


With an estimated cost of only 6,630, I had high hopes for this one. Alas, once again I was forced to cancel the query at the five-minute mark. 27,683 rows. Not much better, I'm afraid. And, as an aside, I'm starting to wonder about these estimated costs. But that's another post for another day.

So where am I going with all of this? Well, there's a reason I haven't given any indication up until this point in the post. You see, it's utterly painful to write this, but...

In this case, a cursor is faster.

Yes, I said it. That evil construct which we as database developers despise, the cursor. Thanks to Paul Nielsen, who revealed this ugly fact to me in a conversation today, I was forced to test this for myself (hoping to prove him wrong, of course). Which is why I started playing around with the solution that I've given so many times on forums. Unfortunately, he is correct.

My next test query, using the first cursor I've written in several years:


DECLARE RunningTotalCursor
CURSOR LOCAL FAST_FORWARD FOR
SELECT TransactionID, ActualCost
FROM Production.TransactionHistory
ORDER BY TransactionID

OPEN RunningTotalCursor

DECLARE @TransactionID INT
DECLARE @ActualCost MONEY

DECLARE @RunningTotal MONEY
SET @RunningTotal = 0

DECLARE @Results TABLE
(
TransactionID INT NOT NULL PRIMARY KEY,
ActualCost MONEY,
RunningTotal MONEY
)

FETCH NEXT FROM RunningTotalCursor
INTO @TransactionID, @ActualCost

WHILE @@FETCH_STATUS = 0
BEGIN
SET @RunningTotal = @RunningTotal + @ActualCost

INSERT @Results
VALUES (@TransactionID, @ActualCost, @RunningTotal)

FETCH NEXT FROM RunningTotalCursor
INTO @TransactionID, @ActualCost
END

CLOSE RunningTotalCursor

DEALLOCATE RunningTotalCursor

SELECT *
FROM @Results
ORDER BY TransactionID


What's really unfortunate about the cursor approach is that you need to use a temporary table if you want to return a single result set to the client. I figured the additional I/O due to the temp table would balance any improvement gains from the cursor approach, thereby rendering my forum responses correct, and Paul wrong. Well, 14 seconds and 113,443 rows later, SSMS and my laptop declared Paul the undisputed Champion of the Cursor.

This cursor makes a lot of sense in this case. The set-based query works by looping over each row of the table, taking a sum of every previous row. So for the 10th row, 10 previous rows also need to be visited. For the 1000th row, 1000 previous rows need to be visited. And so on. The larger the set gets, the worse performance will be--and that's not going to be a merely linear decrease in performance. Think about this: Using the set-based method to find the running sum over a set of 100 rows, 5050 total rows need to be visited. For a set of 200 rows, the query processor needs to visit 20100 total rows -- a four-fold increase in the amount of work that must be done to satisfy the query (O((N^2)/2), for those who are a bit more algorithmically minded.)

The cursor, on the other hand, needs to visit each row exactly once (O(N)). By maintaining the running count in a variable, there is no need to re-visit previous rows. And as my laptop was so happy to show me, the I/O cost due to the temp table does not overshadow the performance improvement of having to visit so many less rows.

So what have we learned today? In my set-based singlemindedness I failed to realize that the cursor does, indeed, have utility. Everything in moderation.

Next steps? I get the feeling that this can be made even faster by employing a CLR routine. Pull the data into a DataReader and loop over that instead, which will completely eliminate the need for a temporary table. Watch for that experiment coming to this space soon.

And next time you hear someone mention how horrible cursors are, remind that person that there is a time and place for everything (and it's called college).

Friday, March 17, 2006

Recommended PHP reading list Recommended PHP readinglist

Recommended PHP reading list:

Recommended PHP reading list

developerWorks




Level: Introductory

Daniel Krook (krook@us.ibm.com), IT Specialist, IBM
Carlos Hoyos (cahoyos@us.ibm.com), IT Architect, IBM

14 Mar 2006

Learn about PHP (Hypertext Preprocessor) with this reading list compiled for programmers and administrators by IBM Web application developers.

Introduction

This list of recommended reading material on PHP is compiled from a variety of online sources by Web application developers in IBM's Global Production Services organization. These resources have been selected with the intention of introducing IT specialists and architects to PHP, providing specific information about development and maintenance, and helping to integrate the technology with IBM products.

PHP is an interpreted programming language run in an environment provided by an open source core engine and extensions whose development is driven by many companies and individuals. As such, this list describes resources that apply to writing PHP programs and to customizing the interpreter's environment. It links to material published by IBM and content provided by others.

This list is updated periodically. Please help us improve it by providing your comments below.


Contents

  1. Overview
  2. Getting started
    1. Development environment
    2. Deployment
    3. Source control
  3. Development
    1. Learning PHP
    2. Advanced PHP
    3. Debugging and profiling
  4. Integration
    1. IBM database servers
    2. IBM Web and application servers
    3. Third-party services
  5. Extension
  6. Migration
    1. Between PHP versions
    2. To IBM database servers
  7. Security
  8. Community and news
    1. Mailing lists
    2. News
    3. Blogs
  9. Other resources
    1. User groups
    2. Presentations
    3. Books
    4. Webcasts
    5. Magazines



Back to top


1. Overview

PHP is a scripting language most often embedded in HTML documents and executed on the server before output is sent to the Web browser. It can also be used as a command-line tool outside of the Web server environment.

PHP is commonly installed in conjunction with other open source software to build Web applications, a platform referred to by the term "LAMP" (which stands for Linux, Apache, MySQL, and PHP), though other components can be used. For example, AIX® in place of Linux®, or DB2® instead of MySQL.

PHP definition
Wikipedia provides an overview of PHP with code samples demonstrating fundamental programming concepts.
Official PHP documentation
The PHP manual is the primary source for information about PHP. It contains a frequently asked questions (FAQ) list, installation guides, language reference, and comprehensive function documentation with user-contributed comments.



Back to top


2. Getting started

2a. Development environment

You can't write PHP without a tool of some sort, be it a simple text editor or full-blown integrated development environment (IDE). Since there are dozens to choose from, here are starting points for a few of the most popular.

Zend Studio
Zend Studio is a commercial IDE from the company that architected the PHP engine. This editor provides syntax highlighting with code assist and supports debugging, source control, documentation, and database connections from within the tool itself.
Eclipse with PHPeclipse
Eclipse is a free open source, platform-independent software framework for delivering rich-client applications. PHPeclipse is an Eclipse plug-in that offers a complete IDE experience, including parser, debugger, code formatter, outline view, and templates. This article provides instructions on configuring and installing Eclipse with the PHPeclipse plug-in.
jEdit
jEdit is a free software text editor written in the Java™ programming language, so it runs in multiple platforms and is extensible via plug-ins. jEdit supports PHP syntax highlighting and additional features, such as syntax validation and code navigation, available through the PHP plug-in PHPParse.

2b. Deployment

When creating or deploying PHP applications, an appropriate environment must be available to run them.

Zend Core for IBM
Zend Core for IBM is a seamless out-of-the-box, easy-to-install, and supported PHP development and production environment. The white paper provides a high-level overview. The installation guide and user guide will help get you up and running quickly.
Install XAMPP for easy, integrated development
Open source stacks such as XAMPP from Apache Friends are simplifying open source development by making it easier to write and distribute applications in a stable, standardized environment. Learn how to install, configure, and back up XAMPP on Mandrake Linux V10.0, learn how to configure and administer XAMPP, and learn how to install your own applications in an XAMPP environment.

2c. Source control

Whether you're collaborating with a team or need to preserve versions of your own files, source control is the answer.

Tools for Writing Better PHP Code -- Version Control with Subversion
Jeff Knight and Andrew Yochum demonstrate how Subversion can be used to manage multiple projects and developers, as well as development and production environments
"Create a blog from scratch with PHP and Subversion"
PHP is a great Web programming language to use when creating dynamic Web sites, such as blogs. This tutorial explains how to build a blog from scratch, while storing data using flat files. The Web site will be backed up on a remote system using Subversion, protecting data in the event of a Web-site crash. Subversion is growing in popularity, and it is a great candidate to back up the site. With Subversion, it's also possible to roll back the Web site to earlier versions of the blog if your server crashes, or if you just didn't like last week's rambling



Back to top


3. Development

3a. Learning PHP

With a development environment in place, you can learn about PHP's core functionality and begin writing code.

Absolute beginners
Zend maintains a collection of PHP 101 introductory tutorials for those who are new to PHP.
"Introduction to LAMP technology"
This tutorial explores the LAMP Web development framework and shows how that framework can help you build applications to solve common business problems. The tutorial begins with an exploration of the LAMP architecture, then introduces fundamental PHP concepts. After a solid grounding of PHP, the tutorial explains MySQL support, with coverage focusing on database concepts and how to access MySQL from PHP. All of these techniques are discussed within the context of a real-world customer management example.
"Getting started with objects with PHP V5"
This article describes the fundamentals of objects and classes in PHP V5, from the very basics through to inheritance, for experienced object-oriented programmers and those who have not yet been introduced to objects.
"Learning PHP, Part 1"
This tutorial is Part 1 of a three-part series that takes you from the most basic PHP script to working with databases and streaming from the file system by documenting the building of a document workflow system. Look at the basics of building a PHP script, including syntax, HTML forms, and database connections.
"Learning PHP, Part 2"
This tutorial is Part 2 of a three-part series that takes you from the most basic PHP script to working with databases and streaming from the file system by documenting the building of a document workflow system. Here, documents are uploaded by users and stored in a non-Web-accessible location for retrieval by the application in Part 3. Also look at working with XML files using DOM and SAX, and at exceptions.
"Learning PHP, Part 3"
This tutorial concludes a three-part series that takes you from the most basic PHP script to working with databases and streaming from the file system by documenting the building of a document workflow system. Learn about using HTTP authentication, streaming files, and how to create objects and exceptions.

3b. Advanced PHP

Once you've gotten your feet wet with PHP, you might choose to enhance, refactor, or extend your application.

"Advanced PHP V5 objects"
The May 2005 IBM developerWorks article "Getting started with objects with PHP V5" covered enough detail to get a reader up and running with the basics of classes and objects in PHP. This article introduces some of PHP V5's more advanced and design-oriented features. Among them are object types, which allow for decoupling the components of a system from one another, creating reusable, extensible, and scalable code.
Introduction to PHP Image Functions
PHP is not limited to creating just HTML output. It can also be used to create and manipulate image files in a variety of image formats, including GIF, PNG, JPG, WBMP, and XPM. Jeff Knight talks about using the GD library and the bundled version in PHP. He covers installation and configuration, a discussion of the image functions themselves, and related topics like patent laws and basic color models and theory.
"Create graphics the smart way with PHP"
Learn to build an object-oriented graphics layer in PHP. Using object-oriented systems can make building complex graphics much easier than building the graphics using the primitives in the standard PHP library.
"How to use regular expressions in PHP"
Regular expressions can provide a powerful way to work with text. Using regular expressions, you can do complex validation of user input, parse user input and file contents, and reformat strings. PHP provides simple methods that let you use POSIX and PCRE regular expressions. Discover the differences between POSIX and PCRE, and how you can use regular expressions and PHP V5.
"Reading and writing the XML DOM with PHP"
Myriad techniques are available for reading and writing XML in PHP. This article presents three methods for reading XML: using the DOM library, using the SAX parser, and using regular expressions. Writing XML using DOM and PHP text templating is also covered.
"Using AJAX with PHP and Sajax"
For years, the goal of creating a truly responsive Web application was hampered by one simple fact of Web development: To change the information on part of a page, a user must reload the entire page. Not anymore. Thanks to asynchronous JavaScript and XML (AJAX), we can now request new content from the server and change just part of a page. This tutorial explains how to use AJAX with PHP and introduces the Simple AJAX Toolkit (Sajax), a tool written in PHP that lets you integrate server-side PHP with JavaScript that makes this work.
PHP 5 and Design Patterns: An Introduction
Matt Zandstra introduces experienced programmers to design patterns in PHP V5. Patterns are shared solutions to commonly encountered problems in software development and can be effectively applied to PHP V5 applications, thanks to its new object-oriented features.

3c. Debugging and profiling

Find and fix application problems.

"Debugging techniques for PHP programmers"
Explore various methods for debugging PHP applications, including turning on error reporting in Apache and PHP, and placing strategic print statements to locate the source of more difficult bugs through a simple example PHP script. The PHPeclipse plug-in for Eclipse, a slick development environment with real-time syntax parsing abilities, is also covered, as is the DBG debugger extension for PHPeclipse.
"PHP Performance Profiling"
Learn how to use the Advanced PHP Debugger (APD) to profile your PHP code. Code profiling helps you identify bottlenecks or inefficient code in your application, enabling you to tune the code where needed.
Advanced PHP Debugger
The Advanced PHP Debugger (APD) is a Zend extension that provides traces suitable for debugging and profiling code, as well as full stack backtrace. Events-based logging is also supported, so different levels of information logging can be set on a script by script basis.
Xdebug
Xdebug is an extension that offers debugging information, including full traces and function/line indicators. Xdebug also includes profiling and script execution analysis.



Back to top


4. Integration

4a. IBM database servers

Traditionally, developers have connected to IBM database servers through the Unified ODBC functions in PHP. IBM now recommends using the new PECL ibm_db2 extension for PHP V4 and PHP V5, or PDO for PHP V5 when building new applications. You can decide which extensions are available when compiling PHP, or use Zend Core for IBM to provide you with preconfigured options.

DB2 and Cloudscape Open Source Development
This is an aggregation of many of the resources for developers planning to use PHP with IBM database servers.
"Built for the Web"
IBM's new partnership with Zend Technologies makes PHP Web development even easier. This article provides an overview of PHP development for IBM database servers and discusses the challenges and solutions at a high level.
IBM DB2 Universal Database, Cloudscape, and Apache Derby
This presentation provides an excellent technical overview of the APIs available for connecting to IBM database servers from PHP.
"Application development with DB2 UDB"
When it comes to application developers, no other database provides the level of tooling and language integration like IBM DB2 Universal Database (DB2 UDB). If you're exploring the world of Web services vis-a-vis a services-oriented architecture (SOA), the DB2 UDB database platform is there for you, whether you chose to write your applications in PHP, the Java language, or .NET. See for yourself just how easy it is to develop applications for the DB2 platform.
"Develop IBM Cloudscape and DB2 Universal Database applications with PHP"
Learn to configure IBM Cloudscape V10.0 and DB2 UDB V8.2 servers for access from PHP V4.x and PHP V5.x. Write database applications using the Unified ODBC extension. Overcome common performance issues due to scrollable cursors and avoid functional limitations in stored procedures.
"Making the Most of PHP with DB2"
Justin Whitney describes the new ibm_db2 extension in detail, showing how to perform data manipulation tasks, as well as error handling, transactions, and prepared statements.
"DB2 Universal Database and the PHP Developer? Absolutely!"
Paul C. Zikopoulos introduces the PHP DB2 APIs and demonstrates the new database connection functionality in Zend Studio provided by the Zend Core for IBM add-in.
"Apache, Cloudscape, and PHP on Linux: A winning combination"
Would you like to know how to build a PHP database application from scratch? This tutorial shows you how to install the DB2 Run Time Client, which allows you to access the IBM Cloudscape database. Also learn to install and configure the Apache Web Server to host the application, and compile and configure the PHP module for Apache. The last part of the tutorial shows how to use the Cloudscape Network Server and Apache to verify our database application.
"Connect PHP to DB2 and Cloudscape via PDO"
PHP V5.1 is set to ship with a new database connectivity layer known as PHP Data Objects (PDO). While PHP has always had good database connectivity, PDO takes PHP to the next level.
"Zend Core for IBM technical roadmap"
The Zend Core for IBM provides a seamless out-of-the-box PHP development and production environment, supported by Zend and integrated with IBM's Cloudscape and DB2 UDB database programs. The product includes native support for XML and Web services in support of increased adoption of SOA. It delivers a rapid development and deployment foundation for database-driven applications and offers an upgrade path from the easy-to-use, lightweight Cloudscape database, to the mission-critical DB2, by providing a consistent API between the two.
"Zend Core for IBM -- A guided tour for PHP developers"
Have you considered setting up PHP V5 on your Linux server, but not had the time to learn how? This article will help guide you through the installation of a PHP V5 environment using the industry's first integrated PHP environment that includes the IBM Cloudscape database server. Installation and configuration is greatly simplified using Zend Core for IBM compared to setting up a complete development and deployment environment from scratch. Zend Core for IBM also provides commonly used PHP extensions and DB2 client libraries to get you connected to your DB2 UDB servers. Support for Zend Core is available from Zend Technologies, a leading provider of PHP products and services, but it is a free download and a time-saver for any PHP developer who wants to build Web applications for IBM Cloudscape or DB2 UDB.
"DB2 Express-C, the developer-friendly alternative"
There are many no-charge Relational Database Management System (RDBMS) options available. Some are open source, and some are available from commercial vendors at no charge. If you are developing applications using C/C++, Java technology, .NET, or PHP and are looking for a proven data server with innovative technology and a growing developer community base deployed in many critical business solutions, it's time to take a look at DB2 Express-C. Find out how to get started quickly using DB2 Express-C for all of your applications, and review an automation and tuning scenario to optimize your application.

4b. IBM Web and application servers

PHP can also be integrated with other IBM software products.

"Hosting PHP applications on the IBM HTTP Server"
IBM maintains its own copy of the Apache Web server and ships it as the IBM HTTP Server, along with its WebSphere® Application Server. This Web server is fundamentally Apache, and as such, can host and run applications written in PHP. Learn the differences between the open source Apache Web server and IBM's version, and view demonstrations of IBM's version running a well-known PHP application.
"Pair J2EE with PHP to implement a common Web application infrastructure"
Conventional thinking often pits the AMP stack of open source technologies -- made up of Apache, MySQL, and PHP -- against Enterprise Java applications and IBM middleware. Sure, each camp has something to fit in the Web server role, each has something for the business layer, and each has something else for the data tier. But can't we all just get along? Of course we can, says Daniel Krook, who shows how and when it can be beneficial to mix and match these once-considered-mutually-exclusive solutions to exploit their relative advantages and develop new and innovative applications.
"Run PHP applications in Apache Geronimo"
PHP has been a popular scripting language for some time. However, with the growing buzz over Java technology and Apache Geronimo, a J2EE-certified application server, many experienced developers shy away from using PHP with Geronimo because only JavaServer Page (JSP) technology is supported out of the box. The PHP Java Bridge solves this problem by providing full support for PHP on Geronimo and for sharing sessions across PHP and JSP scripts.

4c. Third-party services

PHP can tie into many third-party services to support complex e-commerce applications.

"Develop apps with Web services and the eBay SDK, Part 1"
The face of eBay that most people are familiar with is the company's Web presence. Learn how to write a small application that allows users to execute ad-hoc queries against eBay through eBay's SOAP API. The application uses the eBay Java SDK. The use case is targeted at a small subset of the API, but you can generally apply the principles.
"Develop apps with Web services and the eBay SDK, Part 2"
Demonstrate good system integration practices. Learn how to develop a Java application using the eBay SOAP SDK. Part 2 of this series focuses on integrating the application with eBay's Web services, using the authentication and authorization system, and making API calls.
"Develop apps with Web services and the eBay SDK, Part 3"
Create applications in PHP V5 that interact with eBay through Web services. Almost half of eBay's transactions occur through its Web services platform. Acquire a solid understanding of the mechanics of the eBay XML API and learn how to use the Services_Ebay PHP extension.
"Create a Web storefront using PHP and PayPal, Part 1"
This series chronicles the building of a Web storefront in PHP using PHP Data Objects to access a Derby database. The storefront includes a user-manageable shopping cart that allows item purchases using PayPal and includes the ability for merchants to notify customers via e-mail on successful orders automatically.
"Create a Web storefront using PHP and PayPal, Part 2"
This series chronicles the building of a Web storefront in PHP using PHP Data Objects to access a Derby database. The storefront includes a user-manageable shopping cart that allows item purchases using PayPal and includes the ability for merchants to notify customers via e-mail on successful orders automatically. Part 2 covers creating shopping carts and making payments via PayPal.
"Create a Web storefront using PHP and PayPal, Part 3"
This series chronicles the building of a Web storefront in PHP using PHP Data Objects to access a Derby database. The storefront includes a user-manageable shopping cart that allows item purchases using PayPal and includes the ability for merchants to notify customers via e-mail on successful orders automatically. This final part covers the addition of transactions, a shipping component, and an e-mail notification feature.
"Create an Amazon storefront using PHP, Part 1"
This is the first of a two-part tutorial that constructs an Amazon storefront using PHP and the Amazon E-Commerce Service (ECS). The storefront allows shoppers to view items displayed in lists or search for specific items in the store.
"Create an Amazon storefront using PHP, Part 2"
This is Part 2 of a two-part tutorial that constructs an Amazon storefront using PHP and the Amazon E-Commerce Service (ECS). Find out how to create a shopping cart, a "browse for similar items" feature, a specialty theme shop, and a collectibles shop.



Back to top


5. Extension

PHP ships with many built-in capabilities, but it can also be easily extended. You can take advantage of pre-written PHP components (PEAR), compile existing packaged C extensions (PECL), or write your own.

PEAR and PECL InfoCenter
Find out how to work with libraries written in PHP or extensions written in C.
Writing extensions for PHP
Sara Golemon provides information on developing custom extensions.
"An introduction to Service Data Objects for PHP"
A team of IBM developers who implemented SDO in PHP rdescribe a real-world example of adding new capability to PHP via a PECL extension. The extension is available for download at the PECL SDO.



Back to top


6. Migration

6a. Between PHP versions

PHP V5 provides many new features and is largely backward-compatible with PHP V4. However, there are important differences that may affect how your application behaves.

PHP 5 InfoCenter
This Zend site introduces PHP V5 and describes what has changed in the newest version.
Migrating from PHP 4 to PHP 5
Get answers to frequently asked questions about migration.
"Why PHP 5 Rocks!"
Learn about upgrading to PHP V5. The overview provided is explored in detail in the author's book.

6b. To IBM database servers

IBM databases offer many features not available in other vendor products.

IBM Redbook: MySQL to DB2 UDB Conversion Guide
DB2 UDB has long been known for its technology leadership. This IBM Redbook is an informative guide that describes how to migrate the database system from MySQL to DB2 UDB V8.1 on Linux and how to convert applications to use DB2 UDB instead of MySQL.



Back to top


7. Security

PHP enables you to build functional applications quickly. This can lead to inadequate error handling and input verification. Consider these common pitfalls before deploying your site.

"Auditing PHP, Part 1"
Chances are that at some point, you've had a concern about the security of a PHP application. When faced with an auditing task, do you know what to look for? This series walks you through PHP and helps you understand it enough to know what to look for when conducting a security audit. Part 1 walks you through understanding the register_globals setting.
PHP Security Consortium
The PHP Security Consortium (PHPSC) is a group of PHP experts who promote best practices for secure PHP development. The PHPSC site contains articles, a PHP security guide, and weekly summaries of PHP security issues.
Top 7 PHP Security Blunders
Pax Dickinson addresses seven common security issues and how to mitigate the risk in your code.
PHP Security Audit HOWTO
Read this talk given by Chris Shiflett to help you analyze your PHP applications for security holes.



Back to top


8. Community and news

8a. Mailing lists

Mailing lists are an excellent resource for getting answers to your PHP installation and development problems. See if there is already an answer in the archives. If not, ask your question. Many user groups have their own mailing lists.

Mailing lists at PHP.net
There are many lists for those interested in PHP. This site includes lists for general and subject-specific topics in PHP development for end users, as well as a few lists for those building the PHP engine itself.

8b. News

PHP gets better every day. Keeping up with what has changed is important.

PHP Weekly Summary
Read Zend's weekly summaries of new code, bugs, fixes, patches and talk.
SecurityFocus Summaries
Keep on top of weekly updates that may affect the security of your PHP applications.

8c. Blogs

Peruse this partial list of blogs by core PHP engine developers and PHP application developers. Following trends here will give you a good idea of what to expect in upcoming versions of PHP, as well as what development best practices to keep on top of.

Ilia Alshanetsky
Ilia Alshanetsky is a PHP speaker, and book and article author.
John Coggeshall
John Coggeshall is a PHP speaker, and book and article author.
Andi Gutmans
Andi Gutmans is an architect of the Zend Engine and co-founder of Zend Technologies.
Grant Hutchison
Grant Hutchison is a senior product manager at IBM responsible for supporting the application development community for IBM database servers, including DB2 UDB, Cloudscape/Apache Derby, and Informix Dynamic Server (IDS).
John Lim
John Lim is a PHP developer.
Mike Lively
Mike Lively is a PHP developer.
php|architect
Visit php|architect, written and published by Marco Tabini.
PHPDeveloper.org
Visit the official blog of PHPDeveloper.org.
Professional PHP Blog
See this blog for PHP programming, Web development, PHP advocacy and best practices.
Derick Rethans
Derick Rethans is a developer of PHP's mcrypt, date and input-filter extensions, bug fixes, additions among other contributions.
Tobias Schlitt
Tobias Schlitt is a PHP developer.
Dan Scott
Dan Scott is the release lead for the ibm_db2 and PDO_INFORMIX extensions, among other contributions to PHP.
Chris Shiflett
Chris Shiflett is a PHP consultant, speaker, and book and article author.
SitePoint
SitePoint is a PHP and Web design information site.
David Sklar
David Sklar is a frequent author and speaker on PHP.
Zeev Suraski
Zeev Suraski is an architect of the Zend Engine and co-founder of Zend Technologies.
Jason Sweat
Jason Sweat is a PHP speaker and book author.
Adam Trachtenberg
Adam Trachtenberg is a PHP speaker, and book and article author.
Andrei Zmievski
Andrei Zmievski, Technical Yahoo at Yahoo!, is a principal developer of PHP.



Back to top


9. Other resources

9a. User groups

User groups are one of the best ways to meet fellow developers in person and regularly hear about current topics from experts.

New York PHP
New York PHP meets at the IBM building in midtown Manhattan on the fourth Tuesday of every month.
PHP.net calendar
The calendar at php.net lists user group meetings for each month.

9b. Presentations

Many speakers at open source or PHP-specific conferences provide their slides online.

Ilia Alshanetsky
See Ilia Alshanetsky's "PHP and Peformance" and other presentations.
Marcus Börger
See Marcus Börger's "PHP Code Camp" and other presentations.
Derick Rethans
See Derick Rethans' "RAD for PHP" and other presentations.
Chris Shiflett
See Chris Shiflett's "PHP Security Briefing" and other presentations.
Talks at php.net
This includes a listing of talks using a PHP presentation system.

9c. Books

There are many books published about PHP. These are some of the ones we find helpful.

Advanced PHP Programming
George Schlossnagle
Apache Derby -- Off to the Races: Includes Details of IBM Cloudscape
Paul C. Zikopoulos, George Baklarz, Dan Scott
Essential PHP Security
Chris Shiflett
Learning PHP 5
David Sklar
PHP and MySQL Web Development
Luke Welling and Laura Thomson
PHP 5 Objects, Patterns, and Practice
Matt Zandstra
Pro PHP Security
Chris Snyder and Michael Southwell
Upgrading to PHP 5
Adam Trachtenberg

9d. Webcasts

Peruse this high-level coverage of PHP related topics.

Building Dynamic Data-Driven Web Applications with PHP and DB2 UDB and Cloudscape
PHP is one of today's fastest growing Web development languages. Learn how easy it is to get started with PHP and use DB2 or Cloudscape as your database server.
Using PHP with XML and Web Services for rapid Web development
PHP, the open source Web development language, is the fastest way to build business-critical, scalable Web applications that tie in with XML and Web services.

9e. Magazines

These are available at newstands or online in PDF format.

DB2 Magazine
DB2 Magazine is a solutions-oriented magazine that gives IT professionals the strategic and technical information they need to work successfully in the IBM data management environment.
International PHP Magazine
International PHP Magazine is a PHP-related e-magazine.
php|architect
php|architect is a monthly magazine dedicated exclusively to professionals who use PHP as part of their everyday work.

BBC NEWS | Health | Masturbation 'cuts cancer risk':

Men could reduce their risk of developing prostate cancer through regular masturbation, researchers suggest.

They say cancer-causing chemicals could build up in the prostate if men do not ejaculate regularly.

And they say sexual intercourse may not have the same protective effect because of the possibility of contracting a sexually transmitted infection, which could increase men's cancer risk.

Australian researchers questioned over 1,000 men who had developed prostate cancer and 1,250 who had not about their sexual habits.

This is a plausible theory
Dr Chris Hiley, Prostate Cancer Charity
They found those who had ejaculated the most between the ages of 20 and 50 were the least likely to develop the cancer.

The protective effect was greatest while the men were in their 20s.

Men who ejaculated more than five times a week were a third less likely to develop prostate cancer later in life.

Fluid

Previous research has suggested that a high number of sexual partners or a high level of sexual activity increased a man's risk of developing prostate cancer by up to 40%.

But the Australian researchers who carried out this study suggest the early work missed the protective effect of ejaculation because it focussed on sexual intercourse, with its associated risk of STIs.

Graham Giles, of the Cancer Council Victoria in Melbourne, who led the research team, told New Scientist: "Had we been able to remove ejaculations associated with sexual intercourse, there should have been an even stronger protective effect of ejaculations."

The researchers suggest that ejaculating may prevent carcinogens accumulating in the prostate gland.

The prostate provides a fluid into semen during ejaculation that activates sperm and prevents them sticking together.

The fluid has high concentrations of substances including potassium, zinc, fructose and citric acid, which are drawn from the bloodstream.

But animal studies have shown carcinogens such as 3-methylchloranthrene, found in cigarette smoke, are also concentrated in the prostate.

'Flushing out'

Dr Giles said fewer ejaculations may mean the carcinogens build up.

"It's a prostatic stagnation hypothesis. The more you flush the ducts out, the less there is to hang around and damage the cells that line them."

A similar connection has been found between breast cancer and breastfeeding, where lactating appeared to "flush out" carcinogens, reduce a woman's risk of the disease, New Scientist reports.

Another theory put forward by the researchers is that ejaculation may induce prostate glands to mature fully, making them less susceptible to carcinogens.

Dr Chris Hiley, head of policy and research at the UK's Prostate Cancer Charity, told BBC News Online: "This is a plausible theory."

She added: "In the same way the human papillomavirus has been linked to cervical cancer, there is a suggestion that bits of prostate cancer may be related to a sexually transmitted infection earlier in life."

Anthony Smith, deputy director of the Australian Research Centre in Sex, Health and Society at La Trobe University in Melbourne, said the research could affect the kind of lifestyle advice doctors give to patients.

"Masturbation is part of people's sexual repertoire.

"If these findings hold up, then it's perfectly reasonable that men should be encouraged to masturbate," he said.

DateADD Oracle Function:

>>Script Language and Platform: Oracle
Returns a new datetime value based on adding an interval to the specified date.

Syntax

DATEADD ( datepart , number, date )

examples

1)Subtract 10 days from '05/APR/2004'

  Select DateADD('dd' , -10, to_date('05/APR/2004')) from dual
------------
03/26/2004

2)ADD 30 days to MAR return

  Select DateADD('dd' , 30, to_date('31-MAR-2003')) from dual
---------
04/30/2003

3) Add 2 months to 29/FEB/2004

  Select DateADD('M' , 2, '29-FEB-2004') from dual;
--------
04/29/2004

4) Add 2 hours to '01-JAN-2003 10:33:44'

   Select to_char(DateADD ( 'h' , 3 , to_date('01-JAN-2003 10:33:44' ,
'dd-MON-YYYY HH:MI:SS') ) ,
'dd-MON-YYYY HH:MI:SS' ) From dual;
---------
01-JAN-2003 01:33:44

Author: George Antony

http://www.databasejournal.com/img/dateADD.sql

----------------------------FUNCTION
DateADD--------------------------------------------
Create or replace Function DateADD(vchDatePart varchar , intOP in int,
dt date)
/***********************************************************************************
--GEO--C-- GAjoseph
--GEO--E-- Select DateADD('dd' , -10, sysdate) from dual
--GEO--E-- Select DateADD('dd' , 30, to_date('31-FEB-2003')) from dual
--GEO--E-- Select dateadd('m', 2 , sysdate), to_char(DateADD ( 'h' , 3 ,
to_date('01-JAN-2003 10:33:44' , 'dd-MON-YYYY HH:MI:SS') ) , 'dd-MON-YYYY
HH:MI:SS' )
, DateADD ( 'h' , 3 , to_date('01-JAN-2003 10:33:44' ,
'dd-MON-YYYY HH:MI:SS') ) From dual;
--GEO--C-- Returns a new datetime value based on adding an interval to the
specified
date.
--GEO--Ex--
Is the parameter that specifies on which part of the date to
return a new value. The table lists the dateparts and abbreviations
recognized by Microsoft® SQL Server™.
Datepart Abbreviations
Year yy, yyyy
Month mm, m
Day dd, d
Hour hh
minute mi, n
second ss, s

************************************************************************************/
return date
as
dd int;
mm int;
yyyy int;
hh int;
NN int;
SS int;
v date;
lintOP int;
Begin
lintOP := intOP;
--GEO--C-- INcreament Days
if upper(vchDatePart) like 'D%' then
return dt + intOP;
end if;
dd := to_number(to_Char(dt,'dd'));
mm := to_number(to_Char(dt,'MM'));
yyyy:= to_number(to_Char(dt,'yyyy'));
HH := to_number(to_Char(dt, 'HH'));
NN := to_number(to_Char(dt, 'MI'));
SS := to_number(to_Char(dt, 'SS'));
--GEO--C-- INcreament Year
if upper(vchDatePart) like 'Y%' then
yyyy:= yyyy+ lintOP;
end if;
--GEO--C-- INcreament Month.
if upper(vchDatePart) like 'M%' then
yyyy:= yyyy+round(lintOP/12);
mm := mm+mod(lintOP,12);
end if;-->MM
if upper(vchDatePart) like 'H%' then
dd := dd + round(lintOP/24);
hh := hh + mod(lintOP,24);
end if;--> hh
if upper(vchDatePart) like 'N%' then
dd := dd + round(lintOP/(24*60));
hh := hh + round(lintOP/60);
NN := NN + mod(lintOP , 60);
end if;--> MInutes
if upper(vchDatePart) like 'S%' then
dd := dd + round(lintOP/(24*60*60));
hh := hh + round(lintOP/60*60);
NN := NN + round(lintOP/60);
NN := NN + MOD(lintOP,60);
end if;--> SS
v := LAST_DAY(to_date('01/'||to_char(mm,'09')||'/'|| to_char(yyyy,
'0009'),'dd/mm/yyyy'));
if dd > to_number(to_Char(v,'DD')) then
dd := to_number(to_Char(v,'DD'));
end if;
return to_date(lpad(dd,2,'0')||to_char(mm,'09')||'/'|| to_char(yyyy,
'0009')||' '||lpad(hh,2,'0')||':'||lpad(NN,2,'0')||':'||lpad(SS,2,'0'),
'dd/mm/yyyy HH24:MI:SS') ;
exception when others then return null ;
End;