04 maj, 2012

Utveckling: Regular Expression Tester

När jag programmerar använder jag reguljära uttryck ofta, som även kallas för Regular Expressions eller kort och gott Regex.

Om Regular Expressions
Jag tänker inte gå igenom hur det fungerar men om ni gärna vill veta så kan jag tipsa om Wikipedia som tyvärr är svårläst men innehåller mycket information http://en.wikipedia.org/wiki/Regular_expression och följande http://www.regular-expressions.info/tutorial.html En annan hemsida som är bra på att förklara detta är PHPs egna dokumentation som ni finner här http://www.php.net/manual/en/reference.pcre.pattern.syntax.php

Här är en av många hemsidor på Internet som erbjuder en testare online, direkt i webbläsaren, där du kan testa dina mönster (patterns), och snygg är den också jämfört med många andra sidor.

Testa regex online
http://www.onlineregularexpression.com

Give it a shot

24 april, 2012

Unix/Linux: Cron jobb med PHP CLI till logg med datum som filnamn

Tips:

Hur man skapar ett cronjobb på Unix/Linux med ett PHP-skript som körs som CLI kommando. Jag vill också att loggfilen sparas med dagens datum utan klockslag.

Observera att sökvägarna kan skilja för er i era miljöer.
  1. Skapa ett php skript som heter cron.php som gör något, t.ex uppdaterar cachade filer och spara den i /home/testuser/public_html/crontest/cron.php
  2. Ta reda på var binären för PHP finns
    $ whereis php
    /usr/local/bin/php
  3. Testkör skriptet och utdata skrivs till terminalen
    $ /usr/local/bin/php /home/testuser/public_html/crontest/cron.php
  4. Testa skriva ut dagens datum år månad datum
    $ date +"%y%m%d"
    120424
     
  5. Skapa en logg-katalog
    $ pwd
    /home/testuser/public_html/crontest

    $ mkdir log
     
  6. Kör skriptet igen men den här gången skickar vi utdata till en extern logg-fil.
    $ /usr/local/bin/php /home/testuser/public_html/crontest/cron.php >> /home/testuser/public_html/crontest/log/cron_`date +"\%y\%m\%d"`.log
     
  7. Lista loggar
    $ ls -latr log
    drwxr-xr-x 6 testuser testuser  4096 Apr 24 09:00 ../
    -rw-r--r-- 1 testuser testuser  1068 Apr 24 09:26 cron_120424.log
    drwxr-xr-x 2 testuser testuser  4096 Apr 24 09:26 ./
     
  8. Skriv ett cron-jobb med verktyget crontab
    # crontab -e
  9. Ange kommandot:
    30 7,12 * * 1-5 /usr/local/bin/php /home/testuser/public_html/crontest/cron.php >> /home/testuser/public_html/crontest/log/cron_`date +"\%y\%m\%d"`.log
  10. Det betyder att ett jobb kommer utföras varje måndag till fredag (1-5) kl 07.30 och 12.30, alla datum och månader. Mitt PHP-skript rensar cache och uppdaterar cache för ett system jag själv har utvecklat, och det behöver köras innan jag börjar varje vardagmorgon och under tiden jag har lunch.

    Smart va!?
  11. Tänk på att rensa de gamla filerna ibland i katalogen "log", vilket du också kan göra med ett cronjobb, för att hålla ordning och reda samt inte fylla disken med loggar som kan bli stora.
  12.  Om du vill kan du även lägga till aktuell timma i loggfilens namn för att få en separat logg för varje cronjobb om de körs exempelvis två gånger per dag vid olika timmar på dygnet.

    Testa följande:
    $ date +"%y%m%d%H"
    12042409

    Lägg bara in ändringen i kommandot som körs i crontab så är allt klart.
Felsökning?
Om du får problem och måste avbryta scriptet kan du kontrollera processen och kör sedan kill på processen PID.

$ ps -ef | grep php
$ kill -9

Loggen för cron-jobb brukar vara /var/log/cron och då är följande kommando bra att använda i ett extra terminalfönster under tiden som du arbetar och felsöker i ett annat:

$ tail -f /var/log/cron

Kolla gärna in stackoverflow också: http://stackoverflow.com/questions/2135478/how-to-simulate-the-environment-cron-executes-a-script-with

Förbättring
Efter att jag har kört lite har jag stött på miljö-problem i cron-miljön (cron environment). Till slut kom jag fram till att istället anropa skriptet som en hemsida och spara resultatet med wget.

Lägg bara in följande kommando i crontab så kommer det funka:
$  /usr/bin/wget -O cron_`date +"\%y\%m\%d\%H"`.log -P /home/testuser/public_html/crontest/tmp/ http://www.test.se/crontest/cron.php?passwd=lösenord-för-cron-jobb-här

.htaccess HTTP Authentication
 Om filen cron.php ligger i en katalog som är skyddad med HTTP Authentication i en .htaccess fil, så kan man tillåta åtkomst till filen cron.php utan att behöva ange användarnamn och lösenord. All annan åtkomst till andra filer i katalogen kräver användarnamn och lösenord.

 /crontest/.htaccess
 AuthType Basic
AuthName "Administration"
AuthUserFile /home/testuser/public_html/crontest/.htpasswd
Require valid-user
<Files "cron.php">
Satisfy any
</Files>



Tjao

31 januari, 2012

PHP: Solution: Access Websitepanel 1.2.0 Hosting API with PHP nusoap - AddUser error - Object reference not set to an instance of an object

Swedish/svenska
Notis: Denna artikel är skriven på engelska för att det är många utländska prorgrammerare som har problem med Websitepanel och dess API. Därför bestämde jag att skriva den på engelska, dels för att hjälpa mig själv och att dela med mig av kunskapen om hur jag löste problemet till alla som söker efter en lösning på problemet.


Some words about this article
I wrote this article/guide because I'm developing a PHP API for Websitepanel using NuSOAP instead of PHP SOAP extension, and I encountered big problems yesterday and this morning. I want to share my solution and show everyone how I solved it.

The problem
When you use PHP to add a new user with the API function AddUser in esUsers.asmx then most of you will encounter problems and get an error like the following:

Object reference not set to an instance of an object

I pulled my hair, I read the specification, I read examples, I googled for a solution but every solution I found was someone saying he/she solved it by switching to PHP's SOAP extension and not using NuSOAP, and they didn't even publish the solution in code. Why oh why. This made it even more difficult. And I'm not the kind of guy that asks questions i forums - I search before I ask.

Debugging
I tried to output NuSOAP debugging information but that was a smack in the face - too much information and it almost looks the same everywhere, and I don't know where to look. A bit further down in the output I saw some trail of what could be wrong, but I already knew that one parameter was not valid, because it was not working. So continuing with the documentation...

Documentation
What about the documentation for the API, you say? It's kind of incomplete and only has a small working example and including information about how to add a new user but not how to use it in code. The documentation only describes the parameters and their values.

Solution?
I found the solution and I could not believe it - it was so simple but at the same time very unclear and frustrating. I should also say that UserExists works without any problems.

Here is code that does not work and almost everyone that tried to solve this in forums on the Internet used the following code.

PHP:
$param = array(
'OwnerId' => "1", // Owner of the account
'RoleId' => "3", // User
'StatusId' => "1", // Active
'IsDemo' => "false",
'IsPeer' => "false",
'Username' => "testuser",
'Password' => "123456abc!",
'Firstname' => "Testfirst",
'Lastname' => "Testlast",
'Email' => "test@test.com",
);

// This code does NOT work!!
$wsp->call('AddUser', array('parameters' => $param),
'http://smbsaas/websitepanel/enterpriseserver',
'http://smbsaas/websitepanel/enterpriseserver/AddUser');
But then I read the specs one more time slowly and focusing on the documentation at the same time. Then I noticed what was wrong.

Here is the SOAP XML specification:
<s:element name="AddUser">
<s:complextype>
<s:sequence>
<s:element minoccurs="0" maxoccurs="1" name="user" type="tns:UserInfo">
<s:element minoccurs="1" maxoccurs="1" name="sendLetter" type="s:boolean">
</s:element></s:element></s:sequence>
</s:complextype>
</s:element>
Can you see that there are 2 named parameters called "user" and "sendLetter"? That means that the call to AddUser requires a multidimensional array, where the index named "user" shall be assigned the array that contains the user details.

In the documentation it says the following:
"All other fields of the 'user' parameter are optional.
Also you may decide to set 'sendLetter' parameter to 'true' if you would like to send user registration notification."

I first thought that the user details array also could include an index called sendLettter but now I know that it should be completly separate.

Ok, here is the solution
The following code does the trick :)

PHP:
$param = array(
'OwnerId' => "1", // Owner of the account
'RoleId' => "3", // User
'StatusId' => "1", // Active
'IsDemo' => "false",
'IsPeer' => "false",
'Username' => "testuser",
'Password' => "123456abc!",
'Firstname' => "Testfirst",
'Lastname' => "Testlast",
'Email' => "test@test.com",
);

// SOLUTION: Create multidimensional array as
// parameter to follow the SOAP XML specification
$user = array(
'user' => $param
// 'sendLetter' => true
);

// This code DOES work!!
$wsp->call('AddUser', array('parameters' => $user),
'http://smbsaas/websitepanel/enterpriseserver',
'http://smbsaas/websitepanel/enterpriseserver/AddUser');
Perfect!

In my Websitepanel Audit log I saw the following information:
Information 1/31/2012 9:19 AM 9:19 AM User Add test1 adminuser

I hope that you really get this working. And have a nice day

Happy programming

// Waschman

Välkomna till bloggen

Välkomna ska ni vara kära besökare. Jag skriver om IT för att det är kul och för att jag vill dela med mig av information och kunskap. Jag försöker hålla bloggen så kategoriserad som möjligt för att ni enklare ska hitta intressanta länkar och artiklar.