Notes on PHP Modules
Working with Databases
With PHP, access to databases is easily possible → Database service of the URZ for MySQL and PostgreSQL databases.
Documentation
- General information: PHP and databases
- MySQL:
The original mysql extension with functions like
mysql_connect
andmysql_query
is no longer supported as of PHP 7. PHP programmers must use one of these improved APIs (Comparison):- PDO – PHP Data Objects: Tutorial with examples – PDO_MYSQL
- mysqli-extension: Description
- MySQL Server Reference Manual
- PostgreSQL:
Security
- Secure secrets for web applications to protect the database password
- Protection against SQL injection
Checking E-mail Addresses
If e-mail addresses are requested in forms, they must be checked before use.
Use the TUCAL function check_mailadr()
for this purpose.
<?php
# sending and destination addresses must be verified –
# do not transfer from a web form without checking!
# Typing errors can happen and malicious entries can be made.
require_once('php/mail.inc'); # defines check_mailadr
$error = check_mailadr($_POST['to']); # Checking the form input "to"
if ($error) {
echo 'Error in the e-mail address: ' . htmlspecialchars($error);
exit;
}
# The function cannot guarantee that the email address
# is 100% correct and a mail arrives there.
# It is checked whether the address is syntactically correct
# and the domain behind the @ exists.
?>
Sending E-mail
PHP can also be used to send e-mails. But attention:
This should not be a function that is publicly accessible or sends a lot of e-mails - if in doubt, please ask!
To ensure that the sender address is set correctly and the character set is determined correctly, there is a separate function of this server:
tuc_mail()
– See description sending e-mails:
<?php
require_once('php/mail.inc'); # defines tuc_mail()
# A recipient
$to = 'John Doe <john.doe@hrz.tu-chemnitz.de>';
# For multiple recipients: array() -> will be sent as Bcc
# $to = array('jane.doe@hrz.tu-chemnitz.de', 'john.doe@hrz.tu-chemnitz.de');
# Sender, must be from *.tu-chemnitz.de!
$from = 'Frank Richter <frank.richter@hrz.tu-chemnitz.de>';
# Subject, possible: Umlauts in UTF-8 or Latin1- (ISO-8859-1)
$subject = 'PHP test';
# Content, also here umlauts possible
$text = 'This is a test message triggered by ' .
$_SERVER['REMOTE_ADDR'];
# Reply to - not set here:
$reply_to = '';
$ok = tuc_mail($to, $from, $subject, $text, $reply_to);
if ($ok === TRUE)
echo "E-mail has been sent.";
else
echo "Sending error: " . htmlspecialchars($ok);
?>
tuc_mail()
function, please be sure to consider the <?php
# You must specify the sender again in the 5th argument of the mail() function,
# so that error mails also arrive at the sender (and not at the server operator).
# Set sender: must be a valid address of the TU Chemnitz!
# Do not copy from a form!
$from = "mail@...tu-chemnitz.de";
# Sending and destination addresses must be verified -
# do not copy from a web form without verification!
require_once('php/mail.inc'); # defines check_mailadr
$error = check_mailadr($_POST['to']);
if ($error) {
echo 'Error in the e-mail address: ' . htmlspecialchars($error);
exit;
}
# $You have to code the $text and $subject correctly yourself.
# Set this sender twice: vvvv vvvvvvv
mail($to, $subject, $text, "From: $from", "-f $from" );
?>
With tuc_mail()
only text mails without attachments can be sent.
For advanced functions, use the PHPMailer
module on the central servers:
- Example
<?php // Example of using PHPMailer to send an HTML e-mail with 2 attachments // Embedding PHPMailer 6.X: require('libphp-phpmailer/autoload.php'); use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; // Create new PHPMailer instance $mail = new PHPMailer; // Sender: Address, plain text $mail->setFrom('...@...tu-chemnitz.de', 'Webmaster'); // Recipient / To: - the real name is optional $mail->addAddress('recipient@domain', 'First_name Name'); // Recipient copy / Cc: // $mail->addCC('user@domain'); // Recipient blind copy/ Bcc: // $mail->addBCC('user@domain'); // $mail->addBCC('user2@domain2'); // Subject $mail->Subject = 'An HTML mail with two attachments'; // Optional: Reply-to: // $mail->addReplyTo('...@...tu-chemnitz.de'); // Optional: Set any mail header $mail->addCustomHeader('X-my-header', 'True'); // Character set of the text content $mail->CharSet = 'UTF-8'; // Reads HTML content from file, converts external images to embedded ones, // and creates text-only alternative for recipients without HTML mail programme $mail->msgHTML(file_get_contents('contentsutf8.html'), dirname(__FILE__)); // If own text-only content is desired: // $mail->AltBody = 'The HTML content should be written as plain text at this point.'; // Attach PDF $mail->addAttachment('file.pdf'); // Attach an appointment in ICS format $mail->addAttachment('appointment.ics', 'invitation', 'quoted-printable', 'text/calendar'); // Send the e-mail, check for errors if ($mail->send()) { echo 'E-mail sent.'; } else { echo 'Error during sending: ' . $mail->ErrorInfo; }
- Tutorial
Disguising E-mail Addresses
E-mail addresses must not appear in plain text on web pages so that advertising mail senders cannot "collect" e-mail addresses. A PHP function can be used to disguise e-mail addresses (and also other data, such as phone numbers):
<?php require_once('php/mail.inc');
# First subdomain displayed
echo prot_mailadr('john.doe@s2006.tu-chemnitz.de');
# cut away after the @:
echo prot_mailadr('jane.doe@s2010.tu-chemnitz.de', 1);
# this also works for a phone number, the 2nd argument: how many chars are displayed:
echo prot_mailadr('0371 / 531 12345', 11);
?>
The generated website states: john.doe@… jane.doe@… 0371 / 531 …
Before the address or data is displayed, you have to type in a code – except for logged in users.
Features for VoIP Telephony
The VoIP telephones of the TU Chemnitz can be controlled via the web.
This is how the dialling of a telephone number on your telephone (with personal registration) can be prepared with a (Click2Dial). There is also a prepared PHP function for this purpose: telnu()
.
<?php require_once('php/tel.inc');
echo "Give us a call: " . telnu('123456');
?>
LDAP Data Query
The central LDAP server of the TU Chemnitz contains essential information about users of the TU. These can also be queried with PHP functions. For your convenience, there are some predefined functions that you can use.
Note: This is personal data. It is essential that you observe the corresponding data protection regulations!
To use it, the file php/ldap.inc
must be included in the page header:
# Embed LDAP functions
require_once('php/ldap.inc');
See also:
Query Data for a Login Indicator
$info = ldap_userinfo('login_identifier');
Queries the LDAP directory for data for the user with 'login_identifier'
and returns a field with corresponding data.
Return Value
An array $info
with attributes and values:
$info['name']
- First name Surname (UTF-8)
$info['nachname']
- Surname (UTF-8)
$info['vorname']
- First name (UTF-8)
$info['mail']
- E-mail address
$info['tel']
- Telephone number
$info['ou']
- Enrolled faculty or structural unit
$info['ous']
- array with possibly several structural units of the person
$info['ounumber']
- Structure number
$info['ounumbers']
- array with possibly several structure numbers of the person
$info['login']
- Log in identifier
$info['addresse']
- Street, postcode City
$info['raum']
- Room number
$info['raumlink']
- Link to Campusfinder for Room
$info['titel']
- Academic title (if registered)
$info['gebaeude']
- obsolete: Building
<?php
# TUCAL
require_once('../../config.inc.en');
seite(__FILE__);
?>
<h1>Information about user otto</h1>
<p>
<?php
require_once('php/ldap.inc');
require_once('php/mail.inc'); # for prot_mailadr
require_once('php/tel.inc'); # for telnu()
$info = ldap_userinfo('otto');
echo '<br />Surname: ' . htmlspecialchars($info['nachname']);
echo '<br />First name: ' . htmlspecialchars($info['vorname']);
# With spam protection for e-mail address
echo '<br />E-mail: ' . prot_mailadr($info['mail']);
# With "click2dial" for local users
echo '<br />Telephone: ' . telnu($info['tel']);
echo '<br />Address: ' . htmlspecialchars($info['adresse']);
echo '<br />Room: ' . htmlspecialchars($info['raum']);
echo '</p><p>The complete array supplied by ldap_userinfo() is:</p>';
echo '<pre>' . print_r($info, true) . '</pre>';
?>
Please note: The public directory contains data of all TU employees. Students can object to the publication of the data - this data is then not accessible. Data of employees on leave or external persons are also not retrievable.
Query Multiple Records According to a Filter
$infos = ldap_info('filter');
You can query records of multiple people using a LDAP filter.
Return Value
A two-dimensional array $infos
sorts by surname, per user found a field with attributes as with ldap_userinfo()
(see above):
$info[0]['name']
- First name Surname (UTF-8) of person 1
$info[0]['nachname']
- Surname (UTF-8) of person 1
- …
- …
$info[1]['name']
- First name Name (UTF-8) of person 2
- …
- …
<?php
# TUCAL
require_once('../../config.inc.en');
seite(__FILE__);
?>
<h1>E-mail and telephone directory for 1342… </h1>
<?php
require_once('php/ldap.inc');
require_once('php/mail.inc'); #for prot_mailadr
require_once('php/tel.inc'); # for telnu()
## Here: Search by structure number 1342…
$infos = ldap_info('ouNumber=1342*');
# two structure numbers, e.g.
# $infos = ldap_info('(|(ouNumber=231533)(ouNumber=231531))');
if (count($infos) <= 0) {
echo "No result ...";
} else {
echo <<<KOPF
<table class="horizontal"><tr><th>Surname</th><th>First name</th><th>E-mail</th><th>Telephone</th></tr>
KOPF;
for ($i = 0; $i < count($infos); $i++) {
echo '<tr>';
echo '<td>' . htmlspecialchars($infos[$i]['nachname']) . '</td>';
echo '<td>' . htmlspecialchars($infos[$i]['vorname']) . '</td>';
# With spam protection for e-mail address
echo '<td>' . prot_mailadr($infos[$i]['mail']) . '</td>';
# With "click2dial" for local users
echo '<td>' . telnu($infos[$i]['tel']) . '</td>';
echo "</tr>\n";
}
echo "</table>\n";
}
?>
Query Data for a Public LDAP Group
$members = ldap_groupinfo('grp:name');
Queries the LDAP directory for the members of the group named 'grp:name'
and returns a field with corresponding data.
Return value
An array $members
with the login identifiers of the group members.
Graphics and PDF Documents
Our PHP installation contains the extension GD for handling graphics. The commercial PDFlib for editing PDF files is no longer available.
To create PDF documents please use LaTeX – Command: pdflatex
.
The PHP instructions:
<?php
// Author: Jens Pönisch https://www-user.tu-chemnitz.de/~poenisch/
require_once('FunctionGraph.class.php');
$graph = new FunctionGraph(600, 400, 10, 5);
// Function name set and valid? If no, then set empty
if (isset($_REQUEST['function']) && $graph->valid_func($_REQUEST['function'])) {
$function = $_REQUEST['function'];
} else {
$function = '';
}
// cmd switches between image and form
if (isset($_REQUEST['cmd']) && $_REQUEST['cmd'] == 'img') {
// Call with parameter img: Calculate image
header('Content-type: image/png');
$graph->drawAxes();
if ($function) {
$graph->drawFunction($function, 0.01);
}
// write image
$graph->writePNG();
$graph->destroy();
} else {
require_once('../../config.inc.en');
seite(__FILE__);
$select = $graph->select_func($function);
$function_r = rawurlencode($function);
?>
<h1>Example: Graphics with the GD extension</h1>
<p>
<img alt="" src="gd.php?cmd=img&function=<?php echo $function_r ?>">
</p>
<form action="#" method="post" target="_self">
<label>new function f(x) = <?php echo $select ?> (x)</label>
<button type="submit" name="cmd" value="form" style="margin-left:4em"><strong>Send</strong></button>
</form>
<?php
}
?>
<?php
class FunctionGraph {
var $x0;
var $y0;
var $x1;
var $y1;
var $posX0;
var $posY0;
var $scale;
var $img;
var $bg;
var $col0;
var $col1;
var $funcs = array('sin', 'cos', 'tan');
function __construct($width, $height, $x1 = 2, $y1 = 2)
{
$this->x0 = -$x1;
$this->y0 = -$y1;
$this->x1 = $x1;
$this->y1 = $y1;
$this->posX0 = $width/2;
$this->posY0 = $height/2;
$this->scale = (double)($width-20)/($this->x1-$this->x0);
$this->img = imagecreate($width, $height);
$this->bg = imagecolorallocate($this->img, 255, 255, 255);
$this->col0 = imagecolorallocate($this->img, 0, 0, 0);
$this->col1 = imagecolorallocate($this->img, 0, 127, 0);
}
function valid_func($f = '') {
return in_array($f, $this->funcs);
}
function select_func($f = '') {
$opts = '';
foreach ($this->funcs as $func) {
$opts .= '<option value="' . htmlspecialchars($func) . '"' . ($func == $f ? ' selected' : '') . '>' . $func . '</option>';
}
return '<select name="function">' . $opts . '</select>';
}
function drawAxes() {
imageline($this->img, $this->posX0 + (int)($this->x0*$this->scale)-2,
$this->posY0,
$this->posX0 + (int)($this->x1*$this->scale)+2,
$this->posY0, $this->col0);
imageline($this->img, $this->posX0,
$this->posY0 - (int)($this->y0*$this->scale)+2,
$this->posX0,
$this->posY0 - (int)($this->y1*$this->scale)-2, $this->col0);
for ($x = 1; $x <= $this->x1; $x += 1) {
imageline($this->img, $this->posX0+(int)($x*$this->scale),
$this->posY0-3,
$this->posX0+(int)($x*$this->scale),
$this->posY0+3, $this->col0);
imageline($this->img, $this->posX0-(int)($x*$this->scale),
$this->posY0-3,
$this->posX0-(int)($x*$this->scale),
$this->posY0+3, $this->col0);
}
for ($y = 1; $y <= $this->y1; $y += 1) {
imageline($this->img, $this->posX0-3,
$this->posY0-(int)($y*$this->scale),
$this->posX0+3,
$this->posY0-(int)($y*$this->scale), $this->col0);
imageline($this->img, $this->posX0-3,
$this->posY0+(int)($y*$this->scale),
$this->posX0+3,
$this->posY0+(int)($y*$this->scale), $this->col0);
}
}
function drawFunction($function, $dx = 0.1) {
$xold = $x = $this->x0;
# eval("\$yold=".$function.";");
$yold = $function($x);
# echo "$function.$yold.";
for ($x += $dx; $x <= $this->x1; $x += $dx) {
# eval("\$y = ".$function.";");
$y = $function($x);
imageline($this->img, $this->posX0+(int)($xold*$this->scale),
$this->posY0-(int)($yold*$this->scale),
$this->posX0+(int)($x*$this->scale),
$this->posY0-(int)($y*$this->scale), $this->col1);
$xold = $x;
$yold = $y;
}
}
function writePNG() {
imagepng($this->img);
}
function destroy() {
imagedestroy($this->img);
}
}
Social Media Functions: "Like!" etc.
This makes it very easy for web authors to integrate "Share" and "Like!" from Facebook as well as recommendations to Twitter and LinkedIn into a website. The 2-click solution for more data protection (only German) of the Heise publishing house was implemented. You can see the representation and function on this page below.
- Advantages: When visiting our websites, no data of our web visitors is transmitted to the services. Only when the user clicks, the functions are integrated and data is transmitted to the providers of the social services.
- Disadvantage: The visitor must click twice to actually trigger the action.
To embed this function, the file php/sm.inc
must be included:
# Use of social media functions
require_once('php/sm.inc');
Please note:
- Browser must support JavaScript, otherwise these functions will not take effect.
- Website must embed jQuery (this is possible by default).
Functions
string sm_share([string $orientation [, NULL, NULL, array $services]])
Generates HTML/Script code for embedding Facebook/Twitter/LinkedIn Functions.
Parameter
$orientation |
'h' (Default), 'v' |
Appearance: horizontal (side by side), vertical (below each other) |
NULL |
Leave empty | is not used, empty string is also possible ( '' ) |
NULL |
Leave empty | is not used, empty string is also possible ( '' ) |
$services |
array() |
Which services, e. g. array('facebook', 'twitter', 'linkedin'); Values see description, option data-services (not everything was implemented by us) |
Return value
HTML text, can be output with echo
.
Displays the social networking functions side by side.
<?php require_once('php/sm.inc');
echo sm_share();
?>
Displays the social networking functions among each other.
<?php require_once('php/sm.inc');
echo sm_share('v', NULL, NULL, array('twitter', 'facebook', 'linkedin'));
?>