В предлагаемом материале рассказывается об основах работы с мерами и единицами измерений с помощью класса Zend_Measure.
Обзор
Класс Zend_Measure и его потомки предоставляют простой и легкий способ работы с системами мер. Используя эти классы, вы можете конвертировать меры в другие единицы измерений того же типа. Они могут прибавляться, вычитаться и сравниваться между собой. Меры могут быть автоматически извлечены из введенных пользователем данных. Поддерживаются многочисленные типы мер и единиц измерения.
Например, вот так можно легко преобразовать метры в ярды.
<?php
$unit = new Zend_Measure(100, Zend_Measure::LENGTH);
echo $unit, ' is equal to ', $unit->convertTo(Zend_Measure_Length::YARD);
100 m is equal to 109.36132983377 yd
Подсказка
Полезно обратить внимание на единый формат данных, который используется для представления различных типов мер и единиц измерений:
Zend_Measure_<TYPE>::NAME_OF_UNIT, где <TYPE> соответствует хорошо известному физическому или численному свойству (подробнее см. «Типы»), а NAME_OF_UNIT - название единицы измерения.
Создание
При создании
нового объекта класса Zend_Measure или одного из его специализированных наследников в конструктор передается до трех параметров (обязательными являются только первые два параметра). Первый параметр - это собственно величина, причем, она может быть представлена в виде целого числа, числа с плавающей запятой или строки. Второй параметр - это тип предыдущего значения (см. «Типы»). Наконец, третий, необязательный, параметр - это язык.
Приведем
несколько примеров создания таких объектов.
<?php
$unit = new Zend_Measure_Length(1234.56, Zend_Measure_Length::STANDARD);
print $unit;
1234.56 m
<?php
$unit = new Zend_Measure_Number('MMVII', Zend_Measure_Number::ROMAN);
print $unit;
MMVII
<?php
$string = 'The current Frequency is 50Hz.';
$unit = new Zend_Measure_Frequency($string, Zend_Measure_Frequency::STANDARD);
print $unit;
50 Hz
Можно также создать объект «основного» класса Zend_Measure, указав в качестве второго параметра тип меры, как показано ниже.
<?php
$unit = new Zend_Measure(331.46, Zend_Measure::SPEED);
print $unit;
331.46 m/s
Вывод
Вывод данных может быть произведен несколькими способами, показанными ниже. Для этого сначала создадим объект, с которым и будем работать впоследствии.
<?php
$unit = new Zend_Measure_Weight(16, Zend_Measure_Weight::STANDARD);
Автоматический вывод. С помощью выражений print или echo на печать выводится непосредствено сам объект. Именно этим способом мы пользовались до сих пор.
print $unit;
16 kg
Вывод значения. Производится с помощью метода getValue().
print $unit->getValue();
16
Тип значения. Производится с помощью метода getType().
print $unit->getType();
KILOGRAM
Замечание
В будущих версиях появится также возможность локализованного вывода.
Манипуляции
С помощью соответствующих методов, рассмотренных ниже, появляется возможность производить различные манипуляции с данными (такие, как преобразование, сложение и вычитание, сравнение и т. п.).
Внимание
К сожалению, в версии Zend Framework 0.8.0 существуют определенные разногласия между поставляемой документацией и реальным кодом. В действительности, некоторые из перечисленных ниже методов доступны только
для объектов класса Zend_Measure, но не его потомков. Таким образом, при необходимости определенныз манипуляций с данными, следует создавать объекты именно этого класса (см. «Создание»). Однако, в этом случае передаваемая конструктору величина должна быть выражена только в стандартных для создаваемого типа мер единицах измерения.
Методы, доступные только для объектов класса
Zend_Measure
convertTo()
add()
sub()
compare()
Преобразование. Возможно при помощи метода convertTo(). В качестве параметра передается запрашиваемый тип данных.
Важно
Преобразование возможно только в рамках текущего класса (то есть, можно преобразовать, например, метры в футы или килограммы в фунты, но не амперы в градусы или ньютоны).
<?php
$unit = new Zend_Measure(1, Zend_Measure::ANGLE);
echo $unit, ' is equal to ', $unit->convertTo(Zend_Measure_Angle::GRAD);
1 rad is equal to 63.661977236758 gr
Сложение и вычитание. Выполняется с помощью методов add() и sub() соответственно. Результат возвращается в виде нового объекта; исходные объекты при этом не изменяются. Возможна организация своего рода цепочечных вычислений.
<?php
$unit1 = new Zend_Measure(1, Zend_Measure::LENGTH);
$unit2 = new Zend_Measure(2, Zend_Measure::LENGTH);
$unit3 = new Zend_Measure(3, Zend_Measure::LENGTH);
print $result = $unit3->add($unit2->sub($unit1)); // 3 + 2 - 1
4 m
Сравнение. С помощью метода equals() можно определить, равны (идентичны) ли два объекта (для утвердительного ответа должны совпадать как их значения, так и типы). Для более полного сравнения служит метод compare(), который возвращает -1, 0 или 1 в зависимости от того, меньше, равен или больше проверяющий объект.
<?php
$unit1 = new Zend_Measure(1, Zend_Measure::LENGTH);
$unit2 = new Zend_Measure(2, Zend_Measure::LENGTH);
$unit3 = new Zend_Measure(2, Zend_Measure::LENGTH);
Zend::dump($unit2->equals($unit1));
bool(false)
Zend::dump($unit2->equals($unit3));
bool(true)
print $unit1->compare($unit2);
-1
print $unit2->compare($unit1);
1
print
$unit2->compare($unit3);
0
Изменение типа. Ручное изменение типа возможно при помощи метода setType().
<?php
$unit = new Zend_Measure(1, Zend_Measure::LENGTH);
$unit->setType(Zend_Measure_Length::CENTIMETER);
print $unit;
100 cm
Изменение значения. Ручное изменение значения возможно при помощи метода setValue(). В качестве второго параметра может быть передана новая единица измерения.
<?php
$unit = new Zend_Measure(0, Zend_Measure::LENGTH);
$unit->setValue(10, Zend_Measure_Length::CENTIMETER);
print $unit;
10 cm
Типы
Класс Zend_Measure и его потомки поддерживают целый ряд разнообразных мер. Получить полный их список можно с помощью метода getAllTypes().
<?php
$unit = new Zend_Measure(0, Zend_Measure::BINARY);
Zend::dump($unit->getAllTypes());
Предложите способ обойти ограничение, связанное с отсутствием поддержки некоторых методов наследниками класса Zend_Measure (см. «Манипуляции»)
и вынуждающее создавать объекты только со стандартными единицами измерений.
Для этого доработайте следующий пример. Пускай необходимо сложить две длины. Если они выражены в стандартных единицах измерения (в данном случае, в метрах), то решение достаточно просто.
<?php
$unit1 = new Zend_Measure(1, Zend_Measure::LENGTH);
$unit2 = new Zend_Measure(2, Zend_Measure::LENGTH);
print $unit1->add($unit2);
3 m
Если же эти длины выражены в других единицах, например, сантиметрах, то создать корректный объект класса Zend_Measure уже не удастся (если только не произвести соответствующие преобразования вручную, что решением, конечно же, не является). С другой стороны, нельзя создать и специализированный объект класса Zend_Measure_Length с подходящей единицей измерения Zend_Measure_Length::SANTIMETER,
так как он не поддерживает метод add().
Какой, тем не менее, существует способ решить проблему?