Deprecated: Creation of dynamic property wpdb::$categories is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$post2cat is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$link2cat is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 668

Deprecated: Return type of WP_Theme::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-theme.php on line 554

Deprecated: Return type of WP_Theme::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-theme.php on line 595

Deprecated: Return type of WP_Theme::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-theme.php on line 535

Deprecated: Return type of WP_Theme::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-theme.php on line 544

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-includes/comment-template.php on line 1745

Deprecated: wp_getimagesize(): Implicitly marking parameter $image_info as nullable is deprecated, the explicit nullable type must be used instead in /home/inovacao/public_html/yeapf.com/wp/wp-includes/media.php on line 5072

Deprecated: Return type of WP_REST_Request::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/rest-api/class-wp-rest-request.php on line 960

Deprecated: Return type of WP_REST_Request::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/rest-api/class-wp-rest-request.php on line 980

Deprecated: Return type of WP_REST_Request::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/rest-api/class-wp-rest-request.php on line 992

Deprecated: Return type of WP_REST_Request::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/rest-api/class-wp-rest-request.php on line 1003

Deprecated: Return type of WP_Block_List::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 151

Deprecated: Return type of WP_Block_List::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 175

Deprecated: Return type of WP_Block_List::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 164

Deprecated: Return type of WP_Block_List::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 186

Deprecated: Return type of WP_Block_List::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 138

Deprecated: Return type of WP_Block_List::offsetExists($index) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 75

Deprecated: Return type of WP_Block_List::offsetGet($index) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 89

Deprecated: Return type of WP_Block_List::offsetSet($index, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 110

Deprecated: Return type of WP_Block_List::offsetUnset($index) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 127

Deprecated: Return type of WP_Block_List::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php on line 199

Deprecated: Jetpack::setup_xmlrpc_handlers(): Implicitly marking parameter $xmlrpc_server as nullable is deprecated, the explicit nullable type must be used instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/class.jetpack.php on line 934

Deprecated: Automattic\Jetpack\Connection\Manager::setup_xmlrpc_handlers(): Implicitly marking parameter $xmlrpc_server as nullable is deprecated, the explicit nullable type must be used instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/vendor/automattic/jetpack-connection/src/class-manager.php on line 123

Deprecated: Creation of dynamic property Automattic\Jetpack\Connection\Manager::$error_handler is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/vendor/automattic/jetpack-connection/src/class-manager.php on line 93

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Instagram_Gallery::$is_wpcom is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-instagram-gallery.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Mailchimp::$wpcom_is_wpcom_only_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-mailchimp.php on line 17

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$wpcom_is_wpcom_only_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 21

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$is_wpcom is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 22

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Gutenberg_Available_Extensions::$wpcom_is_site_specific_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/gutenberg-available-extensions.php on line 20

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_wpcom_only_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_site_specific_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 24

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Subscribers::$wpcom_is_wpcom_only_endpoint is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/subscribers.php on line 15

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/extensions/blocks/podcast-player/podcast-player.php on line 160

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/extensions/blocks/podcast-player/podcast-player.php on line 160

Deprecated: Creation of dynamic property POMO_FileReader::$is_overloaded is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 26

Deprecated: Creation of dynamic property POMO_FileReader::$_pos is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 29

Deprecated: Creation of dynamic property POMO_FileReader::$_f is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 160

Deprecated: Creation of dynamic property MO::$_gettext_select_plural_form is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/translations.php on line 293

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property Publicize_UI::$in_jetpack is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/publicize.php on line 53

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/widgets/migrate-to-core/image-widget.php on line 195

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/widgets/migrate-to-core/gallery-widget.php on line 56

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/calypsoify/class-jetpack-calypsoify.php on line 130

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/calypsoify/class-jetpack-calypsoify.php on line 131

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/calypsoify/class-jetpack-calypsoify.php on line 135

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/calypsoify/class-jetpack-calypsoify.php on line 136

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/calypsoify/class-jetpack-calypsoify.php on line 137

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 219

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 220

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 227

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 229

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 231

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 248

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 249

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 267

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 268

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 270

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 271

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 273

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/simple-payments/simple-payments.php on line 275

Deprecated: Creation of dynamic property POMO_FileReader::$is_overloaded is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 26

Deprecated: Creation of dynamic property POMO_FileReader::$_pos is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 29

Deprecated: Creation of dynamic property POMO_FileReader::$_f is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/streams.php on line 160

Deprecated: Creation of dynamic property MO::$_gettext_select_plural_form is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/pomo/translations.php on line 293

Deprecated: Creation of dynamic property WPCOM_Widget_Goodreads::$shelves is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/widgets/goodreads.php on line 33

Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/script-loader.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$skip_inner_blocks is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-type.php on line 347

Deprecated: Creation of dynamic property Jetpack_Shortcode_Unavailable::$shortcodes is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/shortcodes/unavailable.php on line 19

Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-term.php on line 198

Warning: Cannot modify header information - headers already sent by (output started at /home/inovacao/public_html/yeapf.com/wp/wp-includes/class-wp-block-list.php:14) in /home/inovacao/public_html/yeapf.com/wp/wp-includes/feed-rss2.php on line 8
Esteban D. Dortta – Blog do Esteban http://www.yeapf.com/wp Espalhar informação no intuito de melhorar a vida de quem programa Mon, 14 Jun 2021 11:36:25 +0000 pt-BR hourly 1 https://wordpress.org/?v=5.8.12 85824673 Short Unique Identifier http://www.yeapf.com/wp/?p=626 Thu, 10 Jun 2021 19:00:01 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=626
Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030

Deprecated: Creation of dynamic property Jetpack_Carousel::$localize_strings is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-content/plugins/jetpack/modules/carousel/jetpack-carousel.php on line 353

Recentemente se me apresentou o problema de migrar um banco de dados de identificadores auto-incrementais para identificadores universais únicos (UUID).

A vantagem do UUID é bem conhecida e acabam sobrepujando as desvantagens. A proposta deste artigo é fornecer uma solução palatável para balancear as vantagens (unicidade principalmente) com as desvantagens (comprimento principalmente)

O que segue é uma pequena implementação de proposta de solução.

<?php
function calcEntropy($str)
{
  // algoritmo de Shannon para cálculo da entropia
  $chars = array();

  $charcount = 0;
  $i         = strlen($str);
  while ($i > 0) {
    $i--;
    $thischar = substr($str, $i, 1);
    if (!isset($chars[ord($thischar)])) {
      $chars[ord($thischar)] = 0;
    }
    $chars[ord($thischar)]++;
    $charcount++;
  }

  $entropy = 0.0;
  foreach ($chars as $val) {
    $p       = $val / $charcount;
    $entropy = $entropy - ($p * log($p, 2));
  }

  return $entropy;
}

function genUuid()
{
  /* ver https://www.php.net/manual/en/function.uniqid.php#94959 */
  return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
    random_int(0, 0xffff), random_int(0, 0xffff),
    random_int(0, 0xffff),
    random_int(0, 0x0fff) | 0x4000,
    random_int(0, 0x3fff) | 0x8000,
    random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0xffff)
  );
}

function dec2hex($number)
{
    $hv = array('0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F');
    $ret = '';
    while($n != '0') {
        $ret = $hv[bcmod($n,'16')].$ret;
        $n = bcdiv($n,'16',0);
    }
    return $ret;
}

function genSUUID($prefix='', $maxLen=18) {
  $charset = "qwertyuiopasdfghjklzxcvbnm" .
             "QWERTYUIOPASDFGHJKLZXCVBNM" .
             "0123456789_";
  $max = strlen($charset);
  $prefix = str_pad($prefix,2,'0',STR_PAD_LEFT);

  $ts = dec2hex(date("y").str_pad(date("z"),3,'0', STR_PAD_LEFT).date("B"));
  $ret = $prefix.$ts;
  while(strlen($ret)<$maxLen) {
    $ret .= substr($charset,random_int(0,$max),1);
  }
  return $ret;
}

// exemplo e cálculo de entropia
$largo = 20;
echo "\nGerando SUUID\n";
echo "# - " . str_pad("SUUID", $largo) . " - Entropia\n";
$e = 0;
for ($i = 0; $i < 10; $i++) {
  $SUUID   = genSUUID("xyz", $largo);
  $entropy = calcEntropy($SUUID);
  $e += $entropy;
  echo "$i - " . $SUUID . " - " . calcEntropy($SUUID) . "\n";
}
echo "Entropia média = " . ($e / 10) . "\n";  

$largo = 12;
echo "\nGerando md5(SUUID)\n";
echo "# - " . str_pad("SUUID", 32) . " - Entropia\n";
$e = 0;
for ($i = 0; $i < 10; $i++) {
  $SUUID   = md5(genSUUID("xyz", $largo));
  $entropy = calcEntropy($SUUID);
  $e += $entropy;
  echo "$i - " . $SUUID . " - " . calcEntropy($SUUID) . "\n";
}
echo "Entropia média = " . ($e / 10) . "\n";

echo "\nGerando UUID canônico\n";
echo "# - " . str_pad("UUID", 36) . " - Entropia\n";
$e = 0;
for ($i = 0; $i < 10; $i++) {
  $uuid    = genUuid();
  $entropy = calcEntropy($uuid);
  $e += $entropy;
  echo "$i - " . $uuid . " - " . calcEntropy($uuid) . "\n";
}
echo "Entropia média = " . ($e / 10) . "\n";
 

A função hex2ec() apenas serve para transformar um decimal em hexadecimal. Deixarei de lado as explicações.

Me concentrarei em genSUUID().

$prefix é um prefixo que usaremos para identificar o servidor. No caso ele aceita até 2 caracteres. Se o conjunto for [ a-z A-Z 0-9 ] cada caractere representa 62 unidades. 62^2=3844 servidores.

$charset é o conjunto de caracteres que iremos usar para representar o identificador.

$ts é a representação do tempo. Ela toma o ano com dois dígitos (acho que nos podemos permitir voltar ao esquema de dois dígitos até o próximo milênio) seguido de um identificador de três dígitos representando o dia no ano (isso é mais econômico que mm/dd) e finalizado pela representação swatch de hora, minuto do timestamp corrente. (Um dia tem 86400 segundos, ao passo que os beats do swatch divide o dia em 1000 partes. Como a ideia aqui não é precisão mas sim unicidade mantendo uma aproximação de quando foi gerado o id, essa resolução é aceitável).

Finalmente o prefixo, a representação do tempo são colados e adicionamos um conjunto de caracteres aleatório do conjunto indicado no $charset.

O que obtemos é um identificador com alta probabilidade de ser único que ao mesmo tempo nos informa em qual servidor e data foi criado com uma resolução de 1 minuto e 26,4 segundos.

Ele é o suficientemente menor que o UUID como para atrair o interesse (lembre que quanto menor seja seu índice no banco, menos RAM vai consumir sua consulta entregando resultados mais velozes)

Ao mesmo tempo, ele tem informação auto-contida que pode orientar na hora de depurar quem deu origem à informação.

Caso for utilizar em produção, lembre que a coluna que irá conter essa informação deve ser Case Sensitive (que aliás, também impacta positivamente na performance) e não precisa ser UTF8 sendo suficiente ASCII.


Atualização Por pura curiosidade implementei o algoritmo de Shannon para calcular a entropia de um string. Depois adicionei dois testes comparativos: o md5() do SUUID e o UUID. Para minha surpresa o SUUID apresenta valores de entropia equivalentes ao UUID mas com menos caracteres.

 Generating SUUID (32 characters)
Number of items represented: 3,850,278.001.389.542.008.853.330.205.498.027,278,336
- SUUID - Entropy
0 - xyz142EB295J5Vt1EzAtc3N6QLIZz2TZ - 4.3903195311148
1 - xyz142EB29 or DgyH2twFrNX9wWlRIAWz - 4.5389097655574
2 - xyz142EB295qSYM3Px7r1OnaUYGHwpro - 4.6875
3 - xyz142EB29Bal8PBFFERITHJKaCBIFCp - 4.2889097655574
4 - xyz142EB29z14aBz7faaRHYvXOQD39IQ - 4.3278195311148
5 - xyz142EB29xqj5boLEDMXI0DbZ4t0l45 - 4.4139097655574
6 - xyz142EB292eJPBvdPWzqk6EycZPCu5U - 4.4528195311148
7 - xyz142EB29i4RDeXRI4gwHc8EyrWWX7x - 4.4139097655574
8 - xyz142EB29q0l54u1KX6oyTiQtVgGrJB - 4.6875
9 - xyz142EB291LMUbRzveltEEdmA4bxurX - 4.4764097655574
Mean entropy = 4.4678007421131
Time consumed per iteration: 0.11599063873291ms
Generating md5(SUUID)
Number of items represented: 340,282,366,920,928,463,463,463,374,607,431,768,211,456
- SUUID - Entropy
0 - 7a9cff898936039c308bca38614e4896 - 3.4772170014625
1 - f2640bbe2e63af0d798d20919a67001f - 3.6678377974034
2 - e912722d4ff09cc23110e38d89ef52b3 - 3.6442475629608
3 - c33cfed4dfd09fbf212e24a6cbe52b7 - 3.6678377974034
4 - 5290ebc045fde2930b297ab905cda543 - 3.5778195311148
5 - 334efcce90828f75408a6503504731c6 - 3.6556390622296
6 - 53d0dc3aa33ba26da902412bcec89cd7 - 3.6639097655574
7 - 2c701ff81578676311a807d78c18f8f2 - 3.2897170014625
8 - 29ce9c482612a2820fae10a76ff686f8 - 3.4261085007312
9 - 97b0cb7e338eff600d4a6555db62e446 - 3.757048827787
Average entropy = 3.5827382848113
Time consumed per iteration: 0.1032829284668ms
Generating Canonical UUID
Number of items represented: 340,282,366,920,928,463,463,463,374,607,431,768,211,456
- UUID - Entropy
0 - be6c96fc-34d9-4fb5-b6f6-82e7b37e6be2 - 3.6150869889135
1 - 2f260cd1-7fff-4066-804a-5af2b113acf6 - 3.6552215288595
2 - 872b0d0d-5acd-4609-88ba-38b8d5e4a3b0 - 3.6597992243145
3 - 90ba1bdb-194e-4035-9b66-2946899b4a81 - 3.541336376912
4 - 7d09dd5c-72e1-4853-8965-54dbd8514823 - 3.6706425444691
5 - 9a54bbd0-aa98-4baf-b604-fceecd0bacb3 - 3.5759228351853
6 - b3d4ab1b-ae8b-4ca4-9675-398f29c6fc48 - 3.8082708345353
7 - be4039f8-997f-4cdb-8a67-2fe2bb42e35f - 3.8082708345353
8 - 37b3d945-6f13-4a0c-b518-7962f7fe8931 - 3.9193819456464
9 - 648b88ad-dbaa-4743-93ee-f5a8ce435232 - 3.7045114597155
Average entropy = 3.6958444573086
Time consumed per iteration: 0.046086311340332ms
]]>
626
Subdomínio para um porto TCP/IP http://www.yeapf.com/wp/?p=619 Fri, 12 Mar 2021 20:14:14 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=619 Uma das serventias do proxy Apache é poder redirecionar as requisições feitas a um subdomínio para um servidor rodando em um porto diferente ou em um endereço diferente ou uma mistura de ambos.

Assim sendo, uma solicitação a db.exemplo.com poderia ser redirecionada para o porto 27017 localizada no mesmo servidor por meio dos seguintes passos:

Verifique que haja uma linha habilitada a carregar a configuração de um arquivo que ainda iremos criar. Esse arquivo o chamaremos de db.exemplo.com.conf.

vi /usr/local/apache2/conf/httpd.conf

Procure por onde estejam os “Include” ou vá até o final do arquivo e adicione a seguinte linha:

Include conf/extra/db.exemplo.com.conf

Salve httpd.conf e edite db.exemplo.com.conf com o seguinte conteúdo:

<VirtualHost *:80>
  ProxyPreserveHost On
  ProxyRequests Off
  ServerName db.exemplo.com
  ProxyPass / http://localhost:27017
  ProxyPassReverse / http://localhost:27017
</VirtualHost>

Caso o módulo proxy do apache não esteja habilitado ainda, os seguintes passos resolvem essa situação:

sudo a2enmod proxy
sudo a2enmod proxy_http

E finalmente, reinicie o Apache2 para ativar a configuração:

sudo service apache2 restart

Isso feito, uma chamada a db.exemplo.com ira a ser atendido pelo servidor que estiver ouvindo no porto 27017 do localhost.

Obviamente que redirecionar para um outro servidor, apenas requer indicar o nome ou IP de dito servidor.

Redirecionando para um servidor Secundário SSL

Porém, pode ser que seja necessário repassar certa informação para um servidor secundário também Apache2. Por exemplo, como quando o servidor primário desvia o atendente a um outro servidor e este outro servidor precisa saber qual o dominio utilizado na requisição original.

Nesse caso, se faz necessário uma solução um pouco mais complexa com a mostrada a seguir em que todas as requisições que chegam a comercio.exemplo.com serão atendidas por srv2.exemplo.com:

<VirtualHost 127.0.0.1:80 _default_:80>
    ServerName comercio.exemplo.com
    Redirect / https://comercio.exemplo.com
</VirtualHost>

<VirtualHost 127.0.0.1:443 _default_:443>
    ServerName comercio.exemplo.com
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPass / http://srv2.exemplo.com:80/
    ProxyPassReverse / http://srv2.exemplo.com:80/
    <Location />
        Order allow,deny
        Allow from all
    </Location>

    SSLCertificateFile %(SSLCertificateFile)
    SSLCertificateKeyFile %(SSLCertificateKeyFile)

    SSLProtocol -ALL +TLSv1.2
    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
    SSLHonorCipherOrder on
    SSLCompression off

    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto: \"https\"

    RequestHeader set X-Forwarded-Port: 443

    Header always set Strict-Transport-Security \"max-age=63072000;\"
    Header set X-Content-Type-Options \"nosniff\"
    Header always append X-Frame-Options \"SAMEORIGIN\"
    Header set Cache-Control \"no-cache, no-store, no-transform\"
    Header set Pragma \"no-cache\"
    Header set X-XSS-Protection \"1;  mode=block\"
    Header set Referrer-Policy: \"strict-origin-when-cross-origin\"
    Header set Content-Security-Policy: \"default-src https: data: 'self' 'unsafe-inline' 'unsafe-eval';\"
    Header set Feature-Policy: \"fullscreen 'self'\"
    Header set x-permitted-cross-domain-policies \"none\"

    FileETag None

</VirtualHost>

]]>
619
Oracle XE 10.2g e PHP 5.6 sobre Ubuntu 20 (Segundo Round) http://www.yeapf.com/wp/?p=616 Tue, 09 Mar 2021 18:57:29 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=616

Continuando a saga, o meu cliente precisou que o sistema dele funcionasse com pdo_oci. Isso fez com que fosse necessário instalar algumas coisas e compilar o módulo do php.

Tudo o aqui feito precisa de ser super-usuário, então a primeira coisa é fazer login como root:

sudo su -

Fiz uma pasta para que fique todo junto e seja fácil copiar as coisas para outro local depois.

cd
mkdir dev
cd dev

Obviamente que a primeira coisa a fazer é atualizar o sistema:

apt update -y && sudo apt upgrade -y

Baixei os seguintes arquivos de https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html:

oracle-instantclient-devel-10.2.0.5-1.x86_64.rpm
oracle-instantclient-basic-10.2.0.5-1.x86_64.rpm

Como o servidor é um Ubuntu (filho do Debian) precisamos a ferramenta alien para poder transformar esses arquivos .rpm em .deb

apt install alien -y

E converti os arquivos usando o alien

alien -d oracle-instantclient-basic-10.2.0.5-1.x86_64.rpm
sudo alien -d oracle-instantclient-devel-10.2.0.5-1.x86_64.rpm

Isso gerou dois arquivos que passei a instalar usando o dpkg

dpkg -i oracle-instantclient-basic_10.2.0.5-2_amd64.deb
dpkg -i oracle-instantclient-devel_10.2.0.5-2_amd64.deb

Com isso, agora temos uma pasta /usr/share/oracle/10.2.0.5/client64/ com a livraria do cliente e uma outra pasta /usr/include/oracle/10.2.0.5/client64/ com os arquivos necessários para a compilação.

Publiquei o ambiente:

export ORACLE_HOME=/usr/share/oracle/10.2.0.5/client64/
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
ldconfig

Sendo que nossa versão de PHP é a 5.6.40 puxei o código fonte dela:

wget http://php.net/get/php-5.6.40.tar.bz2/from/a/mirror -O php-5.6.40.tar.bz2

Expandi o arquivo:

tar xjf php-5.6.40.tar.bz2

E preparei a pasta do módulo para compilá-lo:

cd php-5.6.40/ext/pdo_oci/
phpize

Isso produz a seguinte saída (que pode variar dependendo da versão de PHP que você está usando)

Configuring for:
PHP Api Version: 20131106
Zend Module Api No: 20131226
Zend Extension Api No: 220131226

No arquivo Makefile.global, adicionei a seguinte linha logo após INSTALL e INSTALL_DATA:

EXTRA_INCLUDES = -I/usr/include/oracle/10.2.0.5/client64

Alterei o `config.m4` adicionando 10.2 à lista das livrarias suportadas

SUPPORTED_LIB_VERS="9.0 10.1 10.2 11.1 12.1"

Alterei o script configure para reconhecer nosso php_pdo_driver.h deixando ele da seguinte forma:

if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then
    pdo_cv_inc_path=$abs_srcdir/ext
elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then 
    pdo_cv_inc_path=$abs_srcdir/ext
elif test -f $prefix/include/php/ext/pdo/php_pdo_driver.h; then 
    pdo_cv_inc_path=$prefix/include/php/ext
elif test -f /root/dev/php-5.6.40/ext/pdo/php_pdo_driver.h; then 
    pdo_cv_inc_path=/root/dev/php-5.6.40/ext/pdo/ 
fi

E (usando o cliente que foi instalado na sessão anterior) rodei o configure assim:

./configure --with-pdo-oci=instantclient,/opt/oracle_instantclient,10.2

Logo (e não tendo dado erros) compilei o módulo:

make

E procedi a instalar a extensão:

make install

Com o que ele nos devolve o local onde a extensão foi instalada:

Installing shared extensions:     /usr/lib/php/20131226/

Criei um arquivo para indicar ao php que desejo carregar a extensão compilada.

vi /etc/php/5.6/mods-available/pdo_oci.ini

Com o seguinte conteúdo:

; priority=20
extension=pdo_oci.so

E habilitei o módulo:

phpenmod pdo_oci

Finalmente reiniciei o apache:

apachectl restart

E comprovei se a extensão foi instalada e habilitada:

php -i | grep -i pdo

Devolvendo-me o seguinte resultado em tela:

PDO
PDO support => enabled
PDO drivers => oci
PDO_OCI
PDO Driver for OCI 8 and later => enabled
PWD => /root/dev/php-5.6.40/ext/pdo_oci
_SERVER["PWD"] => /root/dev/php-5.6.40/ext/pdo_oci

Evidentemente que essa extensão depende de ter a pasta /root/dev/php-5.6.40/ext/pdo_oci e caso seja necessário é possível instalar em outra pasta. Mas isso já não é o caso.

]]>
616
Oracle XE 10.2g e PHP 5.6 sobre Ubuntu 20 http://www.yeapf.com/wp/?p=601 Thu, 11 Feb 2021 02:36:18 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=601
Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030

Recentemente me solicitaram colaborar em um problema de conexão entre OracleXE 10.2g e PHP 5.6

Por serem duas plataformas antigas, precisei montar meus servidores para emular tal situação.

Como na descrição não veio se era Apache ou Nginx e o comum era usar o Apache2 e me indicaram estar rodando em Ubuntu20, optei por Apache2.

Este, então, é o roteiro que segui para construir um laboratório que emulasse essa situação. Levantei dois servidores. Um para conter o Oracle XE e outro para o LAMP assim podia realizar meus testes.

O que se segue é o relato da saga.

Repare que estamos rodando sempre como root. Caso queira usar um usuário (como de fato é o certo a fazer) basta adicionar o sudo antes de cada comando.

No nosso caso é root pois os contêineres OpenVZ já rodam em ambiente seguro.

Garantir os templates do OpenVZ

Usamos OpenVZ para criarmos nossas VPS. A imagem do CentOS 7 já tínhamos, mas nos faltava a do Ubuntu. Começamos por ela.
Após uma busca, achamos este repositório:
https://plug-mirror.rcac.purdue.edu/ubuntu-cloud/releases/20.04/release/
Mas ele se mostrou inadequado.
Optamos então por usar o template do Ubuntu 16 disponível em http://mirror.yandex.ru/mirrors/download.openvz.org/template/precreated/

Criação da primeira VPS

Se bem temos nosso próprio script para criarmos as VPS preferi colocar linha por linha o que foi feito para que fique mais claro… e de quebra alguém se interessa em OpenVZ

$ vzctl create 104 --ostemplate ubuntu-16.04-x86_64 --config basic
$ vzctl set 104 --save --name lamp $ vzctl set 104 --save --onboot yes 
$ vzctl set 104 --save --hostname lamp.InovacaoSistemas.com.br 
$ vzctl set 104 --save --ipadd 192.168.1.104/24 
$ vzctl set 104 --save --searchdomain InovacaoSistemas.com.br
$ vzctl set 104 --save --nameserver 1.1.1.1 --nameserver 8.8.4.4 
$ vzctl set 104 --save --cpus 2 
$ vzctl set 104 --save --ram 512M 
$ vzctl set 104 --save --swap 1G 
$ vzctl set 104 --save --diskspace 20G 
$ vzctl start 104 
$ vzctl exec 104 passwd 
$ vzctl exec 104 apt-get update -y

Atualização para Ubuntu 20.04

Após instalarmos o Ubuntu 16, procedemos com um upgrade para termos um 20.04 rodando o do-release-upgrade.
O problema é que como escolhemos a imagem mínima, tivemos que primeiro instalar a ferramenta e logo a seguir atualizar o sistema.

$ apt install ubuntu-release-upgrader-core
$ apt update -y
$ apt upgrade -y

Primeiro atualizamos de 16.04 para 18.04


$ do-release-upgrade

E mais uma vez para irmos de 18.04 para 20.04


$ apt update -y
$ apt upgrade -y
$ do-release-upgrade --mode=server --quiet

Como é uma atualização de uma instalação nova, respondemos que sim a todas as perguntas…. como se fossemos usuários Windows.

Uma vez feito isso, reiniciamos a máquina e testamos algumas coisas para ver se estava tudo ok.

Como nos pode ser útil ter um Ubuntu 20, decidimos guardar uma cópia na forma de template.

$ vzctl stop 104
$ cd /vz/private/104
$ tar -cvzpf /vz/template/cache/ubuntu-20.04-server-amd64.tar.gz .

Mas isso não faz parte do roteiro. Foi apenas um agradável desvio.

Criação da segunda VPS

A segunda máquina é uma CentOS 7 mas a criamos usando o script e a chamada ficou assim:

$ ./createCentos7VM.sh 102 oracleXE inovacaosistemas.com.br

Instalando o Oracle 10.2 XE no CentOS

Dentro do CentOS realizamos as seguintes operações:

$ yum install epel-release
$ yum update -y
$ yum install libaio bc flex -y
$ yum install install glibc.i686
$ wget http://ftp.cs.stanford.edu/pub/fedora/6/i386/oracle-xe-10.2.0.1-1.0.i386.rpm
$ rpm -ivh oracle-xe-10.2.0.1-1.0.i386.rpm
$ /etc/init.d/oracle-xe configure

No arquivo /etc/bashrc adicionamos uma chamada ao script que constrói o ambiente dentro do qual os comandos do oracle podem funcionar como a seguir

. /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh

(não esqueça do ponto seguido de um espaço no inicio)

Liberamos algumas portas no firewall assim

$ firewall-cmd --permanent --zone=public --add-port=8080/tcp
$ firewall-cmd --permanent --zone=public --add-port=1521/tcp
$ firewall-cmd --reload

Feito isso, criamos a partir do nosso micro um túnel assim:

$ ssh root@192.168.1.102 -L8080:localhost:8080

Isso nos permitiu abrir o navegador localmente com o seguinte endereço:

http://localhost:8080/apex

Usando o APEX, criamos um usuário como mostramos nesta figura:

Esse usuário e senha é o que usaremos mais adiante para testarmos nossa conexão.

Instalando o Apache2 e o PHP5.6 no Ubuntu

Instalamos o apache2 da seguinte maneira

$ apt get install apache2 -y

Como não nos interessa problemas de domínio, segurança e coisas parecidas, deixamos ela como está.

Já instalar o php5.6 requer um pouco mais de voltas. Mais ou menos com quando um cachorro vai deitar.

$ apt install software-properties-common 
$ add-apt-repository ppa:ondrej/php
$ apt update -y
$ apt install -y php5.6

Criamos um pequeno script para nos mostrar a situação em /var/www/html chamado info.php com o seguinte conteúdo:

<?php
  phpinfo();

E abrimos ele no navegador para visualizar se o PHP estava rodando e em qual versão

http://192.168.1.104/info.php

Reiniciamos o servidor para termos certeza que tudo está ok.

Instalando o cliente Oracle no Ubuntu

Fizemos download do basic-10.2.0.5.0-linux.zip e sdk-10.2.0.5.0-linux.zip deste endereço: https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

E depois o instalamos

$ unzip basic-10.2.0.5.0-linux-x64.zip
$ mkdir /opt/oracle_instantclient
$ mv instantclient_10_2/* /opt/oracle_instantclient/
$ unzip ../sdk-10.2.0.5.0-linux.zip
$ mv instantclient_10_2/* /opt/oracle_instantclient/
$ cd /opt/oracle_instantclient/
$ ln -s libclntsh.so.10.1 libclntsh.so
$ apt-get install php5.6-dev -y
$ apt-get install libaio-dev -y
$ apt-get install php5.6-common php5.6-xml php5.6-cli -y
$ apt-get install php-pear -y
$ pecl channel-update pecl.php.net
$ pecl install oci8-2.0.12

Na hora em que pergunte onde está o cliente instantclient, devemos indicar instantclient,/opt/oracle_instantclient

Dando tudo certo com a compilação, devemos adicionar o oci8.so aos php.ini da seguinte forma:

$ echo "extension=oci8.so" >> /etc/php/5.6/apache2/php.ini
$ echo "extension=oci8.so" >> /etc/php/5.6/cli/php.ini

Outra coisa que precisamos fazer é indicar onde ficou a livraria do instant-client como segue:

$ echo /opt/oracle_instantclient/ > /etc/ld.so.conf.d/oracle-instantclient.conf
$ ldconfig

E finalmente reiniciamos o apache2 assim:

$ apachectl restart

Navegando novamente no http://192.168.1.104/info.php podemos confirmar que o OCI está configurado como mostra a figura

Finalmente, testamos nossa conexão com um pequeno script colocado em /var/www/html sob o nome testar-conexao-oracle.php com este conteúdo:

<?php
$conn = oci_connect("teste", "abc123", "192.168.1.102/XE");
if ($conn) {
echo "Conexão realizada com sucesso\n";
} else {
echo "Erro na conexão com o banco de dados\n";
}

E testamos o mesmo desde a linha de comando:

$ php testar-oci8.php

Se tudo ocorreu bem ele nos mostrará que a conexão deu certo.

Podemos também testar usando o navegador:

http://192.168.1.104/testar-oci8.php

Bem, com isso chegamos ao fim do problema da conexão com vanilla PHP.

]]>
601
Uma forma de ajustar o MTU http://www.yeapf.com/wp/?p=590 Fri, 27 Mar 2020 10:49:15 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=590

MTU significa Max Transmission Unit e determina o tamanho máximo que um pacote de dados pode ter. Um tamanho grande de MTU, está associado a uma redução no overhead ao passo que um tamanho pequeno de MTU pode reduzir a demora de resposta da rede.

Esse tamanho não é o mesmo para todos os provedores de internet, já que depende das capacidades físicas da rede. Logo, deve ser ajustada para obter a melhor performance. Esse ajuste pode ser feito de forma automática ou manual.

Uma forma de descobrir o melhor MTU é usando o comando ping. Antes de começar, mude o MTU do seu roteador para o valor máximo (Geralmente é 1500).

Depois, de um micro conectado nessa rede, utilize o seguinte comando para determinar a média do seu ping:

$ ping -c 10  -D -s 1462 1.1.1.1 | tail -1| awk '{print $4}' | cut -d '/' -f 2

Na linha acima, estamos usando uma largura de pacote de 1453.

Instruimos o ping a repetir por 10 vezes com um alvo bem conhecido (1.1.1.1). Passamos o resultado disso para três comandos que nos darão a média de pingar 10 vezes o alvo com o tamanho do pacote determinado.

Devemos repetir esse teste várias vezes em diferentes momentos para obtermos uma média aceitável. Isto é, o tempo mais baixo de resposta em ms.

Comece com valores 10 bytes para cima e 10 bytes para baixo até chegar em um valor aproximadamente bom. Provavelmente obtenha mais de um valor aceitavel dependendo do período do dia. Depois que chege em valores mais ou menos aceitáveis, comece a alterar o tamanho do pacote de 5 em 5 e depois de 1 em 1 até que você se sinta satisfeito com a velocidade obtida.

Esse valor de pacote não é o de MTU. Para obter o valor de MTU, você deve adicionar os 28 Bytes de overhead ao tamanho do pacote.

Uma vez obtido o valor do MTU, modifique no seu router

No meu caso, por exemplo, eu cheguei a um tamanho de pacote de 1453 Bytes que dá um MTU 1481. Com isso a média de ping ao alvo escolhido ficou em 62ms.

A seguir a minha tabela com alguns valores de testes para poderem visualizar como foi minha experiência:

Pacote (Bytes)Tempo (ms)
147284.242
145269.618
1442120.935
145587.894
145360.283

Essa tabela não é exaustiva e obtive valores de resposta bem diferentes usando o mesmo tamanho de pacote. Nesses casos, acabei descartando o tamanho do pacote inteiro ficando com a ideia que “nesse tamanho oscila muito” para acalmar o pequeno monstro cientista.

Caso esteja usando Windows, o comando ping fica assim:

C:\> ping -f -l 1449 1.1.1.1
]]>
590
Criando um ambiente de desenvolvimento LAMP http://www.yeapf.com/wp/?p=583 Thu, 05 Mar 2020 18:52:09 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=583 LAMP é um acrônimo representando Linux, Apache, MySQL e PHP

Um ambiente LAMP nos dá os elementos básicos para poder programar.

Como o alvo é programar sobre um servidor e não sobre ambiente Desktop, a instalação será sem GUI mas fique livre para faze-lo. Eu mesmo não tenho recursos tão abundantes assim para pôr interface gráfica em um servidor que vou controlar via ssh.

Escolhemos Ubuntu por ser o Linux mais simples de instalar e usar no dia a dia do desenvolvedor. Para produção costumamos colocar CentOS que é mais leve porém às vezes mais nojentinho de configurar.

Se você já tem uma VM com Ubuntu, pode pular para “Instalando LAMP” lá no final

  1. Baixe a última versão estável do Ubuntu

    No momento de escrever este artigo, estava na 18.04.4 LTS (Sempre escolha as versões 04 que tem maior durabilidade garantida pela Cannonical)

    https://ubuntu.com/download/server

  2. Crie uma máquina virtual

    a. Verifique se o local de armazenamento existe

    No meu caso, eu deixo todas as máquinas virtuais em uma pasta chamada ‘VirtualBoxes’ alocada na raiz do usuário; isto é: /home/esteban/VirtualBoxes. Então, e não tem uma pasta assim e quer cria-la faça como segue:

    $ mkdir ~/VirtualBoxes
    b. Crie sua máquina virtual usando o seguinte comando:
    $ VBoxManage createvm --name MeuLAMP --ostype Debian_64 --register --basefolder ~/VirtualBoxes/ 

    O VBoxManage vai responder alguma coisa assim:

    Virtual machine 'MeuLAMP' is created and registered.
    UUID: 3156aee4-8a2e-46dd-ae69-54533c78ff5f
    Settings file: '/Users/estebandortta/VirtualBoxes/MeuLAMP/MeuLAMP.vbox'
    c. Modifique ela para seus parâmetros mínimos.

    No caso 512MB de RAM, IOAPIC ligado e uma interface de rede em modo bridge (ponte). Repare que no meu caso, a placa de rede que vai ser usada como ponte é a chamada en1. Por isso que usei ela. No seu caso isso é diferente.

    Para obter uma lista das placas conectadas na sua máquina, pode usar o seguinte comando:

    $ ifconfig | grep "^[a-z0-9]*\:" | awk '{ print $1 }'

    Uma vez determinado o nome, pode proceder como segue:

    $ VBoxManage modifyvm MeuLAMP --ioapic on
    $ VBoxManage modifyvm MeuLAMP --memory 512 --vram 128
    $ VBoxManage modifyvm MeuLAMP --nic1 Bridged  --bridgeadapter1 en1

    Estes comandos, se bem executados, não devolvem coisa alguma na tela.

    d. Agora vamos adicionar um disco

    Ele será de tamanho típico (70GB) para este tipo de serviço mas pode ser menor ou maior. Depende de sua capacidade. Não recomendo abaixo de 40GB. Repare que meu download ficou em ~/Downloads/OS/Linux/ubuntu-18.04.3-live-server-amd64.iso então modifique conforme necessário.

    $ VBoxManage createhd --filename ~/VirtualBoxes/MeuLAMP/MeuLAMP_DISK.vdi --size 70000 --format VDI
    $ VBoxManage storagectl MeuLAMP --name "SATA Controller" --add sata --controller IntelAhci
    $ VBoxManage internalcommands sethduuid ~/VirtualBoxes/MeuLAMP/MeuLAMP_DISK.vdi
    $ VBoxManage storageattach MeuLAMP --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium  ~/VirtualBoxes/MeuLAMP/MeuLAMP_DISK.vdi
    $ VBoxManage storagectl MeuLAMP --name "IDE Controller" --add ide --controller PIIX4
    $ VBoxManage storageattach MeuLAMP --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium ~/Downloads/OS/Linux/ubuntu-18.04.3-live-server-amd64.iso
    $ VBoxManage modifyvm MeuLAMP --boot1 dvd --boot2 disk --boot3 none --boot4 none
    e. Configuramos acesso remoto

    O configuramos via vrde para podermos lidar com a tela dela no inicio e se alguma coisa acontece com ela durante o uso posterior. O porto (no caso 10004) é da sua escolha apenas use um que não exista.

    $ VBoxManage modifyvm MeuLAMP --vrde on
    $ VBoxManage modifyvm MeuLAMP --vrdemulticon on --vrdeport 10004
    f. Finalmente, inicie sua máquina para poder configura-la
    $ VBoxManage startvm MeuLAMP

    Lembre que posteriormente, podemos usar este comando para iniciar ela “sem-cabeça”. Ou seja, sem interface. Com isso vc poupará alguns recursos de CPU, GPU, RAM, etc. Usamos isso em produção.

    $ VBoxHeadless --startvm MeuLAMP
  3. Coisas a serem feitas durante a instalação

    a. Escolha a partição que ocupa o disco inteiro e sem LVM.

    Em produção é o contrário. Ou seja, particionamos o disco diferente e usamos LVM que nos permite adicionar mais discos e não apenas mudar o tamanho.

    b. Configure seu usuário.

    Este é um usuário comum mas com direitos administrativos. Não esqueça a senha mas também não a anote no post-it. Chegado o caso anote ela na manga da camisa. A mulher vai se encarregar de fixar ela na sua memória.

    b. Não esqueça de instalar o SSH (Ele vai oferecer OpenSSH logo após particionar o disco)

    É importante ter seu SSH instalado pois é por meio dele que você vai acessar sua máquina. Sim, você não está sendo treinado para ser um gnutellinha da vida. Um acesso SSH te libera da exigência brutal de ter uma banda muito larga já que os comandos e seus retornos são textuais.

    c. Deixe o restante como está.

    Se precisar de proxy, indique no momento adequado.

    d. Aguarde até o fim.

    Ele vai demorar baixando as atualizações de segurança. Deixe rolar. Melhor agora do que depois.

    c. Caso a atualização der problemas escolha “Cancel Update and Reboot”
  4. Coisas a serem feitas após a instalação

    Quando chegue ao final da instalação, o sistema instalado vai reiniciar. Observe que ele solicita para remover o disco de instalação. Como colocamos o disco de instalação como “CD-ROM”, o instalador já se encarregou de “ejetar” o mesmo. É só reiniciar (dando ENTER na VM) e boa.

    Assim que a máquina reinicie, ingresse nela usando seu usuário e senha cadastrado no primeiro passo.

    Na primeira vez, ele vai estar ainda configurando algumas coisas, então tenha paciência.

    A única coisa que interessa dessa entrada, é pegar o IP dela para poder acessa-la via SSH.

    Obtemos esse IP usando o comando ifconfig da seguinte maneira:

    esteban@meulamp:~$ ifconfig

    Ele nos devolverá alguma coisa assim:

    enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
           inet 192.168.0.152  netmask 255.255.255.0  broadcast 192.168.0.255
           inet6 fe80::a00:27ff:fe07:8f8b  prefixlen 64  scopeid 0x20<link>
           ether 08:00:27:07:8f:8b  txqueuelen 1000  (Ethernet)
           RX packets 855  bytes 642531 (642.5 KB)
           RX errors 0  dropped 2  overruns 0  frame 0
           TX packets 243  bytes 30082 (30.0 KB)
           TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
           inet 127.0.0.1  netmask 255.0.0.0
           inet6 ::1  prefixlen 128  scopeid 0x10<host>
           loop  txqueuelen 1000  (Local Loopback)
           RX packets 104  bytes 8136 (8.1 KB)
           RX errors 0  dropped 0  overruns 0  frame 0
           TX packets 104  bytes 8136 (8.1 KB)
           TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    Mas desse trambolho todo só nos interessa o IP da primeira placa. A ‘lo’ é uma placa virtual que existe em todo linux para que a pilha TCP/IP funcione. (Lembre que X11 é um servidor que roda no seu próprio micro e sobre TCP/IP. Assim como ele há um monte de programas que esperam que vc tenha uma pilha TCP/IP ativa. Por isso ela está embutida).

    Então, simplificamos para o seguinte comando para obtermos o IP da máquina:

    esteban@meulamp:~$ ifconfig | grep -w inet | grep -vw 127 | awk '{ print $2 }'

    Com este comando mais simples, direto, eficiente, bonito, fácil de lembrar, obtemos apenas o IP da máquina. No meu caso a saída se resume a isto aqui:

    192.168.0.152

    Agora, devemos reconhecer que é um saco ter que abrir a máquina virtual para saber qual IP que ele pegou. Por outro lado, precisamos de essa informação para trabalhar. Comigo acontece de que geralmente não posso deixar ela com IP fixo já que uso ela em diferentes redes.

    Uma forma de solucionar isso, é que a própria máquina mostre o IP que pegou na tela antes do login. Desta forma, apenas abrir a tela da VM (Lebre que vamos usar sem tela) já nos mostra esse IP. (Eu não sei vocês, mas eu esqueço dos IPs fixos tb, então eu coloco em tudo quanto é máquina)

    Para conseguir isso, vamos modificar o arquivo /etc/issue que é o arquivo que é mostrado no fim do processo de inicialização e logo antes do login.

    Como minha placa chama-se enp0s3 (Detesto esses nomes novos, gostava de quando eram eth0 por exemplo) o meu arquivo /etc/issue fica assim:

    Ubuntu 18.04.4 LTS n l
    enp0s3: 4{enp0s3}
    ------------------------------------------

    Ao reiniciar a máquina virtual, lá estará a informação que preciso para poder trabalhar.

  5. Configurando seu acesso via SSH

    Usar uma máquina virtual via tela é pedir para sofrer. Ela é mais lenta, não tem jeito.

    Mesmo se instalou a GUI (como é o caso de Windows Desktop por exemplo que não tem como instalar sem interface gráfica) o melhor é o acesso remoto. Claro, há exeções, mas a regra é essa.

    Bem, antes de se apaixonar pelo ssh, você tem que ser triducidado por ele.

    Se seu ambiente é Windows, um cliente ssh potável é o PuTTY (https://putty.org) mas o que eu mais gosto é Cygwin (https://www.cygwin.com). Agora, com isso de que o Windows10 já vem com bash (e Ubuntu) embarcado, imagino que o melhor seja usar a opção que vem embarcada.

    Eu vou supor que está usando Linux, Cygwin ou bash embarcado.

    a. Acesse sua máquina virtual desde a linha de comandos da sua máquina. No meu caso fica assim:
    $ ssh esteban@192.168.0.152

    Por ser a primeira vez, o meu bash responde assim:

    The authenticity of host '192.168.0.152 (192.168.0.152)' can't be established.
    ECDSA key fingerprint is SHA256:poNetFdUSSEYn8tH2Mu7Vy7NLdq25lFaCJ449rt2bjw.
    Are you sure you want to continue connecting (yes/no)?

    Ao que eu respondo que sim em inglês fluente. Ou seja “yes” e não apenas “y”

    Com isso o servidor fica registrado na lista de alvos conhecidos pelo ssh

    Logo apósi digito a senha que registrei na hora da instalação e pronto, estou nele.

    Mas vamos sair, porque -não sei vocês- mas eu detesto ter que lembrar de senhas e tal.

    Para sair, digitamos exit ou usamos ctrl-d que dá na mesma.

    SÓ CONTINUE SE VOLTOU NA SUA MÁQUINA MÃE

    b. Tem ou não um par de chaves na sua máquina mãe?

    Pode acontecer que você não tenha um par de chaves criadas. Para verificar se tem, use o seguinte comando:

    $ ls ~/.ssh/*

    Se ele mostra dois arquivos id_rsa e id_rsa.pub, você já tem as chaves criadas e não há de que se preocupar (a não ser, claro que tenha criado as chaves com senha e as tenha esquecido)

    Se ele mostrar alguma coisa parecida com a imagem abaixo é porque você não tem o par de chaves:

    ls: cannot access '/home/esteban/.ssh/': No such file or directory

    Caso, então, tenha que criar esse par de chaves, o fazemos usando o seguinte comando:

    $ ssh-keygen

    Deixe que o demônio do usuário Windows entre em você e dé ENTER até o final. Dessa forma criará um par de chaves que não precisam senha para serem usadas. (Em produção você coloca senha nelas)

    A saída fica mais ou menos assim:

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/esteban/.ssh/id_rsa): 
    Created directory '/home/esteban/.ssh'.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/esteban/.ssh/id_rsa.
    Your public key has been saved in /home/esteban/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:1h2/DAEBwxLLwiKYFSyY3FSiFtWRAvO1t8snCgGxCAY esteban@meulamp
    The key's randomart image is:
    +---[RSA 2048]----+
    |EOB=o++oo.o.     |
    |O+O+o+o... .     |
    |=*..+.oo    o    |
    |.... .. .. . +   |
    |   .   .S . o .  |
    |    . ...    o . |
    |   .   + .    o  |
    |    . . o        |
    |     .           |
    +----[SHA256]-----+
    c. Copie sua chave pública para a VM

    Para poder facilitar o acesso via SSH, você agora vai copiar sua chave pública para a máquina que criou. No meu caso fica assim:

    $ ssh-copy-id esteban@192.168.0.152

    E ele produzirá uma saída semelhante a esta

    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/estebandortta/.ssh/id_rsa.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    esteban@192.168.0.152's password: 
    
    Number of key(s) added:        1
    
    Now try logging into the machine, with:   "ssh 'esteban@192.168.0.152'"
    and check to make sure that only the key(s) you wanted were added.

    Eu digitei a senha da VM quando me pediu. Se você criou seu par de chaves com senha, vai pedir essa senha tb. Ai vc vai lembrar o porque que eu disse para colocar sem senha.

    Bem, a partir deste momento entrar na sua máquina virtual via ssh será tão simples como fazer

    $ ssh esteban@192.168.0.152

    E ele deve ir sem pedir senha (a não ser que o par de chaves…bla bla bla)

  6. Instalando o LAMP

    Entraremos na virtual. Use o comando similar ao seguinte

    $ ssh esteban@192.168.0.152
    a. Instale o básico

    O que é o básico no LAMP?

    Bom, sendo que está no Linux, só falta AMP (Apache, MySQL e PHP)

    Existem pacotes prontos que faremos bem em evitar pois buscamos aprender o que é – de fato – importante.

    Primeiro atualizaremos a base instalada (isso pode levar um tempinho a primeira vez)

    esteban@meulamp:~$ sudo apt-get update -y

    Ele vai pedir a senha de usuário para poder fazer sudo

    Em lugar do MySQL vamos instalar o MariaDB. (MariaDB é um fork de MySQL que o criador de MySQL fez quando abandonou a Oracle. O criador do MySQL tinha ido para a Oracle contando com que a Oracle ia manter seus tentáculos longe e manter o MySQL aberto. Como isso não aconteceu, ele foi embora. Perdeu o nome MySQL mas o software é o mesmo… e manteve a dignidade que – nos tempos que correm – digamos que é importante)

    esteban@meulamp:~$ sudo apt-get install apache2 php mariadb-server mariadb-client php-mysql -y
    
    Dependendo de sua distribuição, pode ser que o apache não esteja configurado para iniciar junto com o sistema. Habilite o apache e inicie ele com estes dois comandos:
    
    esteban@meulamp:~$ sudo systemctl enable apache2
    esteban@meulamp:~$ sudo systemctl start apache2
    

    Dessa forma, quando você reiniciar sua máquina, o apache estará funcionando mas para continuar agora, ele também estará funcionando.

    b.Configure o acesso ao banco de dados

    Uma vez instalado, é bom configurar o banco de dados. Basicamente precisamos que ele seja seguro o suficiente como para trabalhar, mas tb que não encha o saco com muitas exigências.

    esteban@meulamp:~$ sudo mysql_secure_installation

    Assim que ele é instalado, o root está sem senha. Então quando perguntado, crie uma senha para root.

    • Depois remova os usuários anónimos
    • Permita acesso remoto pelo root (em produção é o contrário)
    • Remova a base de testes
    • Recarregue sua tabela de privilegios

    Pronto, seu MariaDB está configurado. Agora reinicie ele:

    esteban@meulamp:~$ sudo systemctl restart mariadb

    E teste o seu acesso local:

    esteban@meulamp:~$ mysql -u root -p

    Se tudo deu certo, você vai ter uma tela parecida com esta:

    Welcome to the MariaDB monitor.  Commands end with ; or g.
    Your MariaDB connection id is 35
    Server version: 10.1.44-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    MariaDB [(none)]> Bye

    Mas, pode ser que sua combinação de Ubuntu/MariaDB esteja meio louca. Geralmente o problema está com o protocolo de autenticação. Nesse caso ele vai mostrar uma saída como a seguinte:

    esteban@meulamp:~$ mysql -u root -p
    Enter password: 
    ERROR 1698 (28000): Access denied for user 'root'@'localhost'

    Se tiver esse problema você pode proceder da seguinte forma primeiro para confirmar o erro e depois para corregi-lo:

    esteban@meulamp:~$ sudo mysql
    MariaDB [(none)]> use mysql;
    MariaDB [mysql]> select user, plugin from user;

    Ele vai mostrar para você uma saida com esta que serve para identificar se esse é seu problema:

    +------+-------------+
    | user | plugin      |
    +------+-------------+
    | root | unix_socket |
    +------+-------------+
    1 row in set (0.00 sec)

    Corrigimos isso assim:

    MariaDB [mysql]> update user set plugin='mysql_native_password' where user='root';
    MariaDB [mysql]> flush privileges;
    MariaDB [mysql]> exit

    Agora, desde seu usuário comum, você deve ser capaz de entrar no mysql localmente

    esteban@meulamp:~$ mysql -u root -p

    Feito isso, volte na sua máquina mãe e tente o acesso ao servidor de banco de dados

    esteban@meulamp:~$ exit
    logout
    Connection to 192.168.0.152 closed.
    $ mysql -u root -p -h 192.168.0.152
    Enter password: 
    ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.0.152' (61)

    No meu caso, esse é o erro que dá. Isso está dizendo que o servidor não está ouvindo no IP indicado.

    Assim que voltamos à VM e corrigimos a configuração do MariaDB

    $ ssh esteban@192.168.0.152
    esteban@meulamp:~$ sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

    Procure pela linha que diz

    bind-address = 127.0.0.1

    e substitua pelo seguinte

    bind-address = *

    Agora reinicie o servidor

    esteban@meulamp:~$ sudo systemctl restart mariadb

    Volte à sua maquina mãe (gosto de chama-la assim… parece com ‘nave mãe’ ao final das contas somos como que alienigenas invadindo as VM da vida)

    esteban@meulamp:~$ logout
    Connection to 192.168.0.152 closed.
    [estebandortta@Estebans-MacBook-Pro ~] mysql -u root -p -h 192.168.0.152
    Enter password: 
    ERROR 1130 (HY000): Host '192.168.0.142' is not allowed to connect to this MariaDB server

    Repare que o erro mudou. Agora nos está dizendo que o nosso host (no caso 192.168.0.142 que é o IP da minha máquina mãe) está impedido de acessar.

    Voltamos à VM e – usando nosso direito de acesso ao banco lá dentro – corrigimos isso assim:

    $ ssh esteban@192.168.0.152
    esteban@meulamp:~$ mysql -u root -p

    E uma vez dentro do mysql fazemos assim:

    MariaDB [(none)]> CREATE USER 'root'@'192.168.%' IDENTIFIED BY 'tr3co';
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.%';
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> exit

    Com isso criamos um novo usuário também chamado root mas com a senha tr3co que pode acessar este servidor desde qualquer micro da rede 192.168.x.x (Repare o uso do coringa ‘%’)

    Voltamos à máquina mãe e testamos o acesso.

    esteban@meulamp:~$ exit
    logout
    Connection to 192.168.0.152 closed.
    
    $ mysql -u root -ps3nha -h 192.168.0.152
    Welcome to the MariaDB monitor.  Commands end with ; or g.
    Your MariaDB connection id is 7
    Server version: 10.1.44-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    MariaDB [(none)]>
    c. Alterando as configurações do usuário

    É necessário que o usuário comum possa escrever na pasta /var/www/html

    A forma mais fácil disso é fazer um sudo chmod -fR 0777 /var/www/html que é o análogo a colocar a saida do vaso direto no ralo do chuveiro. Funciona.

    O certo mesmo é fazer com que o usuário comum (que tb é administrativo) consiga escrever na pasta /var/www/html

    A primeira coisa a fazer é verificar em que grupo o apache2 trabalha. O seguinte comando faz isso:

    esteban@meulamp:~$ ps aux | grep apache | awk '{ print $1 }' | grep -v "root|esteban" | uniq

    No meu caso ele me devolve www-data. Para eu, usuário comum, poder escrever nas pastas desse grupo, devo pertencer ao mesmo.

    Você pode verificar os direitos que seu usuário comum tem da seguinte forma:

    esteban@meulamp:~$ id esteban
    uid=1000(esteban) gid=1000(esteban) groups=1000(esteban),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)

    Como você pode observar, o meu usuário comum não pertence ao grupo www-data. Adicionamos ele ao grupo com o seguinte comando:

    esteban@meulamp:~$ sudo usermod -a -G www-data esteban

    E podemos verificar com o comando id que de fato ele foi adicionado:

    esteban@meulamp:~$ id esteban
    uid=1000(esteban) gid=1000(esteban) groups=1000(esteban),4(adm),24(cdrom),27(sudo),30(dip),33(www-data),46(plugdev),108(lxd)

    Só que se você for ver, ainda não pode criar arquivos na pasta /var/www/html:

    esteban@meulamp:~$ touch /var/www/html/info.php 
    touch: cannot touch '/var/www/html/info.php': Permission denied

    A forma mais limpa de resolver isto é se apropriando da pasta /var/www/html:

    esteban@meulamp:~$ sudo chown esteban /var/www/html
    esteban@meulamp:~$ sudo chgrp www-data /var/www/html

    Uma vez feito isso, você pode criar o arquivo /var/www/html/info.php com o seguinte conteúdo para comprovar o correto funcionamento e instalação de tudo:

    <?php
     phpinfo();
    ?>

    Proceda a testar a sua configuração solicitando ao apache que processe esse arquivo e mostre a saida na tela. Ou seja, navegue.

    http://192.168.0.152/info.php

    Se tudo ocorreu bem, tem que aparecer uma lista com as configurações atuais do apache, o php e o mysql.

  7. Criando o primeiro programa

    Bom, se tudo deu certo, é hora de criarmos o primeiro programa.

    Mas para que o teste seja completo, vamos criar primeiro um banco de dados

    esteban@meulamp:~$ mysql -u root -p
    Welcome to the MariaDB monitor.  Commands end with ; or g.
    Your MariaDB connection id is 7
    Server version: 10.1.44-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    MariaDB [(none)]> create database meuTeste;
    Query OK, 1 row affected (0.00 sec)
    
    MariaDB [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | meuTeste           |
    | mysql              |
    | performance_schema |
    +--------------------+
    4 rows in set (0.00 sec)

    Uma vez criado o banco meuTeste (que por enquanto não tem tabelas) vamos escrever nosso primeiro programa.

    esteban@meulamp:~$ nano /var/www/html/testar-conexao.php

    Digitando o seguinte lá dentro:

    <?php
     $con = mysqli_connect("localhost:3306", "root", "czyhnp");
     if ($con) {
       $db = mysqli_select_db("meuTeste")
       echo "Ok";
     } else {
       echo "Impossível conectar";
     }

    Confirmamos que tudo esteja bem com ele usando o seguinte comando:

    esteban@meulamp:~$ php -l /var/www/html/testar-conexao.php 

    Corrigimos os erros (se você estava copiando-colando tem um erro) usando o nano e o testamos pedindo para o apache2 usar seu pre-processador, passar para o php, este realizar o serviço, devolver seu resultado numa pipe textual, e o apache2 devolver para a conexão para que o navegador renderize isso perante nós. Simplificando: navegue

    http://192.168.0.152/testar-conexao.php

  8. Finalmente, reinicie

    Com isso tudo pronto, reinice seu servidor e teste novamente para ver que tudo esteja ok

    esteban@meulamp:~$ sudo reboot

    Se os passos foram seguidos, tudo tem que continuar funcionando ok.

    Lembre apenas que da próxima vez, vc pode levantar sua maquina virtual apenas usando a opção HeadLess

    $ VBoxHeadless --startvm MeuLAMP
]]>
583
Emulando Raspberry no Desktop http://www.yeapf.com/wp/?p=570 Tue, 08 Oct 2019 00:52:03 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=570
Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030

Um dos nosso produtos funciona sobre Raspberry Pi que é – dito seja de passagem – uma plataforma e tantas, não apenas para investigar, inventar mas também para produzir e ganhar o pão nosso de cada dia.

Todavia, o que mais me causava atrito era ter que toda vez criar uma imagem, gravar ela na SD, espetar isso no Raspberry, esperar ligar, comprovar as mudanças, etc.

Receita de bolo

  1. Garanta que tenha tudo instalado
    $ sudo apt-get install -y qemu-system
  2. Baixe a imagem do raspberry (ou qualquer outro sistema operacional) do seu interesse: https://www.raspberrypi.org/downloads/. Aos fins do exemplo, digamos que estamos usando raspbian-buster-lite.
  3. Depois baixe os kernels daqui: https://github.com/dhruvvyas90/qemu-rpi-kernel
    $ cd ~/Downloads/
    $ mkdir dev
    $ git clone https://github.com/dhruvvyas90/qemu-rpi-kernel.git
  4. Crie uma pasta de fácil acesso:
    $ mkdir ~/qemu-mv
  5. Expanda o buster que baixou no ponto 1 para a pasta criada
    $ cd ~/qemu-mv
    $ unzip ~/Downloads/2019-06-20-raspbian-buster-lite.zip
  6. Agora precisamos pegar as dimensões da imagem para poder modifica-la:
    $ fdisk -l ~/qmu-mv/2019-06-20-raspbian-buster-lite.img
  7. Repare que o tamanho do setor é 512 bytes e que a partição Linux começa no setor 540672. Multiplicando os dois obtemos 276824064. Com essa informação, montamos o disco para mudarmos dois arquivos que estão dentro da imagem:
    1. Criamos uma pasta e montamos a imagem lá:
      $ sudo mkdir /mnt/raspberry
      $ sudo mount -v -o offset=276824064 -t ext4 2019-06-20-raspbian-buster-lite.img /mnt/raspbian
    2. Edite o arquivo ld.so.preload
      $ sudo nano /mnt/raspbian/etc/ld.so.preload
    3. Comente todas as linhas colocando um ‘#’ no inicio de cada linha.
    4. Agora edite o arquivo /etc/fstab
      $ sudo nano /etc/fstab
    5. Substitua as referências para /dev/sda1 (vfat) e /dev/sda2 (ext4)
    6. Desmonte a unidade
      $ sudo umount /mnt/raspbian
  8. Copie o kernel para dentro desta pasta
    $ cp ~/Downloads/dev/qemu-rpi-kernel/kernel-qemu-4.19.50-buster ~/qemu-mv/
  9. Agora crie um arquivo com o conteúdo indicado abaixo
    $ nano ~/qemu-mv/meu-rb.sh
  10. E dê direitos de execução ao script
    $ sudo chmod +x ~/qemu-mv/meu-rb.sh

Conteúdo do script meu-rb.sh

#!/bin/bash
qemu-system-arm \
-kernel ~/work/qemu_mv/kernel-qemu-4.19.50-buster \
-cpu arm1176 \
-m 256 \
-M versatilepb \
-serial stdio \
-append "root=/dev/sda2 rootfstype=ext4 rw" \
-drive file=~/work/qemu_mv/2019-06-20-raspbian-buster-lite.img,format=raw,index=0,media=disk \
-no-reboot \
-net nic \
-net user,hostfwd=tcp::5022-:22 

Com isso feito, é apenas rodar o script que o qemu abrirá uma sessão com o raspberry/arm.

Modificações feitas aqui são salvas de forma permanente (instalação de pacotes, configuração do seu software, volcado de banco de dados, etc) na imagem.

Uma vez que sua máquina esteja rodando como desejado, desligue-a. Reverta o feito nos passos 7.2 e 7.4 e grave a imagem em uma SD

Com certeza seu processo de desenvolvimento e entrega será mais rápido ficando apenas para depurar in situ aquelas coisas que o emulador não consegue entregar como interface com hardware via GPIO por exemplo.

]]>
570
Objetive-C em Ubuntu http://www.yeapf.com/wp/?p=562 Mon, 09 Sep 2019 23:46:17 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=562
Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030

Estou pesquisando algumas coisas. Entre elas, Objetive-C. Me resulta interessante porque me permite – supostamente – usar o mesmo código fonte para compilar para Windows, Linux e Mac entre outros.

Então fiz o seguinte script (testado em buster/sid) que instala o que é necessário e faz os scripts necessários para facilitar a compilação.

#!/bin/bash
# instalador de gnustep e compilador para debian/ubuntu

sudo apt install -y clang gnustep gnustep-devel && \
 cc=`cat ~/.bashrc | grep GNUstep\.sh | wc -l` && \
 (
     if [ $cc -eq 0 ]; then
       echo ". /usr/share/GNUstep/Makefiles/GNUstep.sh" >> ~/.bashrc
     fi
 ) && \
 (
   cc=`cat ~/.bashrc | grep gnuc | wc -l`
   if [ $cc -eq 0 ]; then
     echo "gnuc() {"  >> ~/.bashrc
     echo "  gcc \$1.m \`gnustep-config --objc-flags\` -lgnustep-base -lobjc -o \$1" >> ~/.bashrc
     echo "}" >> ~/.bashrc
   fi
 )

Espero lhe seja útil.

Abç

]]>
562
Monitorando mudança de aba em SPA http://www.yeapf.com/wp/?p=557 Fri, 23 Aug 2019 15:23:06 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=557
Deprecated: ltrim(): Passing null to parameter #1 ($string) of type string is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/wp-db.php on line 3030
Aguardar por um evento é melhor...

YeAPF! tem um gestor de abas bem simples de usar que permite construir um SPA (Single Page Application) com muita facilidade.

Tendo várias abas, uma coisa que quase com certeza vai querer fazer é responder dinamicamente a essa mudança atualizando – por exemplo – o conteúdo de algum campo ou coisa assim.

Digamos que no seu HTML tem a seguinte estrutura de abas:

<div class=tnContainer>
  <div class=tnTab id=vw_boas_vindas>
    <img id=imagemBoasVindas>
  </div>
  <div class=tnTab id=vw_cadastro>
    <form ...>
      ...
    </form>
  </div>
  <div class=tnTab id=vw_listagem>
    <table ...>
    </table>
  </div>
</div>

E imaginemos também que cada vez que você envia o usuário a sua tela de boas vindas quer mudar a imagem de uma lista que seu aplicativo tem.

Seu javascript ficaria assim:

/* lista de imagens */
var imagens = ["rio.jpg", "montanha.jpg", "deserto.png", "cascata.jpeg"];
/* indice da imagem atual */
var imagemAtual = 0;

function monitorarMudancaAba() {
  /* verifico se a aba mostrada é a de boas-vindas */
  if (mTabNav.currentTab().id=="vw_boas_vindas") {
    /* calculo o seguinte indice da imagem */
    imagemAtual = (imagemAtual + 1) % imagens.length;
    /* altero a imagem a ser mostrada */
    y$("imagemBoasVindas").src="img/"+imagens[imagemAtual++];
  }
}

function inicializacao() {
  /* adiciono um gestor de eventos do objeto window */
  window.addEventListener('tabshow', monitorarMudancaAba);
}

/* indico ao YeAPF! para chamar a rotina de inicialização assim que estiver tudo pronto */
addOnLoadManager(inicializacao);

Com isso, toda vez que a aba for alterada, há um monitoramento sobre essa mudança e uma alteração da imagem de boas vindas que era o objetivo procurado.

Obvio que sua criatividade vai levar este simples exemplo a níveis maiores.

]]>
557
Gerando dados ficticios para testes http://www.yeapf.com/wp/?p=501 Wed, 12 Dec 2018 16:40:16 +0000
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /home/inovacao/public_html/yeapf.com/wp/wp-includes/category.php on line 383
http://www.yeapf.com/wp/?p=501 Convenhamos que nem sempre é fácil gerar uma boa quantidade de dados como para testar um sistema apenas com o uso da imaginação. Não que a imaginação não seja fertil, mas sim que cansa andar imaginando apenas sobre um único assunto. Faz parte da natureza da imaginação interessar-se por coisas alheias ao foco em que queremos que ela fique… seria mais ou menos como a vida de um artista e daquele que vive de vender sua produção musical: o primeiro DVD realmente é bacana, o segundo é uma tentativa pífia de manter o fluxo de dinheiro e para o terceiro tudo quanto é tesão não existe mais.

Bom, ilustrações fonográficas à parte, quando se trata de um sistema precisamos de gerar vários regitros com qualquer tipo de informação contanto ele preencha certos requisitos. Por exemplo: o cpf tem que ser válido.

Incluimos no YeAPF 0.8.61-170 uma pequena função que pode fazer a diferença na hora de criar esses dados: fillFieldsWithJunk()

Você pode usa-la para criar apenas um único campo ou um registro inteiro.

Mas um exemplo pode ser mais util que mil palavras. Digamos que quero gerar um registro com dados aleatórios. Isto (que chamarei de testar-geracao-dados.php) resolve:

require_once "yeapf.php";
$campos = array(     
  array(
      "id" => "nome",
      "type" => "text",
      "className" => "male name",
      "maxlength" => "25"
    ),
    array(
      "id" => "cpf",
      "type" => "text",
      "className" => "cpf"
    ),
    array(
      "id" => "endereco",
      "type" => "text",
      "maxlength" => "70"
    ),
    array(
      "id" => "site",
      "type" => "url"
    ),
    array(
      "id" => "telefone",
      "type" => "tel"
    ),
    array(
      "id" => "email",
      "type" => "email"
    ),
    array(
      "id" => "cep",
      "type" => "text",
      "className" => "cep-cliente"
    )
  );
/* gero os dados */
$dados = fillFieldsWithJunk($campos);
/* imprimo na tela */
print_r($dados);

Agora, desde a linha de comando executamos ele usando o php

$ php testar-geracao-dados.php

Pronto, cada vez que rodemos, obteremos um novo conjunto de dados.

O seguinte exemplo geraremos esses dados em JSON. Pelo bem da simplicidade apenas mostraremos as linhas modificadas (que são as últimas)

/* gero os dados */
$dados = fillFieldsWithJunk($campos);
/* imprimo na tela como JSON */
echo json_encode($dados);

E finalmente, faremos um teste preenchedo 2378 registros de uma tabela que chamaremos clientes (foje ao escopo deste artigo mostrar criação de tabelas, conexão com o banco de dados, etc)

Novamente, mostraremos as linhas modificadas que são as últimas:

$quantidadeRegistros = 2378;
while ($quantidadeRegistros-->0) {
  $dados = fillFieldsWithJunk($campos);
  $sql=save_form_sql($dados, "clientes", "id");
  db_sql($sql);
}

Pronto, seu banco já está cheio de…. bom, o que fillFieldsWithJunk() conseguir gerar.

 

]]>
501