I found a solution (similar to yours in some way) by adding following lines to my doctrine.php file:
$q = file_get_contents('../configs/sql/routines.sql');
$conn = Doctrine_Manager::connection();
$conn->execute($q);
Now, everytime I execute ./doctrine build-all-reload a following script is executed:
DROP FUNCTION IF EXISTS DIST;
CREATE FUNCTION DIST (fi11 DOUBLE, ksi11 DOUBLE, fi22 DOUBLE, ksi22 DOUBLE)
  RETURNS DOUBLE
   DETERMINISTIC
    BEGIN
     DECLARE d DOUBLE;
     DECLARE fi1 DOUBLE;
     DECLARE fi2 DOUBLE;
     DECLARE ksi1 DOUBLE;
     DECLARE ksi2 DOUBLE;
     SET fi1 = PI()*(fi11)/180;
     SET fi2 = PI()*(fi22)/180;
     SET ksi1 = PI()*(ksi11)/180;
     SET ksi2 =PI()*(ksi22)/180;
     SET d = ACOS((SIN(fi1)*SIN(fi2))+(COS(fi1)*COS(fi2)*COS((ksi1-ksi2))))*6371.0;
     RETURN d;
    END;
This solution is maybe not elegant, but works for me:)
I am not planning to change database from MySQL.
After that i can use DIST function in Doctrine Queries and it works several times faster than using standard build-in-function implementation, and is much shorter.
$q->where('DIST(a.lan, a.lon, b.lan, b.lon) < ?', array(2.0));
istead of
$q->where('ACOS((SIN(...)... ... wrrrr ;-P ))*6371.0 < ?', array(2.0));
Thanks for your help.