Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.199
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. A variável globlal do PHP só é útil quando não existir nenhum formuário no projeto. Se houver, a variável global é inútil, e só o $_SESSION é capaz de salvar um valor até fechar o navegador.
  2. O código da Gemini funciona, só que demora uma hora para ser executado. Eu alterei o tempo de espera para um minuto com sleep(10). Eu gostei do código da Gemini, ela começa com a conexão mysqli e em seguida ela usa os métodos do PDO, só não sei se é possível obter um array de objetos. Para transformar a conexão numa variável global, ela não pode ser definido numa classe mas num sim num módulo comum como acontece com o arquivo config.php onde são definidos as constantes. A seguir o mesmo código da Gemini só que usando as classes: arquivo /Astudy/Controles/Controle.php <?php require 'Modelos/Conexao.php'; class Controle { public function entrada($nome, $apto, $entrou) { global $conexao; $sql = "INSERT INTO entradas (nome, apto, entrou) VALUES (?, ?, ?)"; $stmt = $conexao->prepare($sql); $stmt->bind_param("sss", $nome, $apto, $entrou); $stmt->execute(); if ($stmt->affected_rows > 0) { echo "Regitrado: $nome (Apto: $apto) - entrou: $entrou <br>"; } else { echo "Problema: $conexao->error"; } $stmt->close(); } function saida($nome, $apto, $saiu) { global $conexao; $sql = "INSERT INTO saidas (nome, apto, saiu) VALUES (?, ?, ?)"; $stmt = $conexao->prepare($sql); $stmt->bind_param("sss", $nome, $apto, $saiu); $stmt->execute(); if ($stmt->affected_rows > 0) { echo "Registrado $nome (Apto: $apto) - saiu: $saiu <br>"; } else { echo "Problema: $conexao->error"; } $stmt->close(); } } arquivo /Astudy/Modelos/Conexao.php <?php $host = "localhost"; $usuario = "root"; $senha = ""; $esquema = "diario"; $conexao = new mysqli($host, $usuario, $senha, $esquema); if ($conexao->connect_error) { die("Falha na conexao: " . $conexao->connect_error); } arquivo /Astudy/index.php <?php require 'Controles/controle.php'; $controle=new Controle; $nome = "John Doe"; $apto = "101"; $entrou = date("Y-m-d H:i"); $controle->entrada ($nome, $apto, $entrou); sleep(10); // 1 minuto $saiu = date("Y-m-d H:i"); $controle->saida($nome, $apto, $saiu);
  3. Depois de cinco anos, eu decidi eliminar a tabela super variável do meu banco de dados; no lugar dele eu uso a variável de sessão que dura enquanto o navegador estiver funcionando. Ontem, no entanto, eu perguntei para a Gemini se ela tinha um código exemplo para controlar o movimento das pessoas no condomínio, e ela me passou o código. O código dela é bem estranho, ela mistura o motor do mysqli com o motor PDO, eu duvido que isso vá funcionar, eu ainda não testei. Mesmo assim, o código dela é o primeiro exemplo que eu vi que alguém usa a variável global. Eu já tinha ouvido falar, mas nunca cheguei a testar. A minha ideia é tentar fazer uma variável global durar enquanto o navegador estiver funcionando, não sei se vou conseguir, mas o meu ponto de partida vai ser o código da Gemini: arquivo index.php <?php $dbHost = "localhost"; $dbUsername = "root"; $dbPassword = ""; $dbName = "diario"; $dbConnection = new mysqli($dbHost, $dbUsername, $dbPassword, $dbName); if ($dbConnection->connect_error) { die("Connection failed: " . $dbConnection->connect_error); } function registerEntry($name, $apartment, $timeIn) { global $dbConnection; $sql = "INSERT INTO entries (name, apartment, time_in) VALUES (?, ?, ?)"; $stmt = $dbConnection->prepare($sql); $stmt->bind_param("sss", $name, $apartment, $timeIn); $stmt->execute(); if ($stmt->affected_rows > 0) { echo "Entry registered successfully for: " . $name . " (Apartment: " . $apartment . ") - Time In: " . $timeIn . "\n"; } else { echo "Error registering entry: " . $dbConnection->error . "\n"; } $stmt->close(); } function registerExit($name, $apartment, $timeOut) { global $dbConnection; $sql = "INSERT INTO exits (name, apartment, time_out) VALUES (?, ?, ?)"; $stmt = $dbConnection->prepare($sql); $stmt->bind_param("sss", $name, $apartment, $timeOut); $stmt->execute(); if ($stmt->affected_rows > 0) { echo "Exit registered successfully for: " . $name . " (Apartment: " . $apartment . ") - Time Out: " . $timeOut . "\n"; } else { echo "Error registering exit: " . $dbConnection->error . "\n"; } $stmt->close(); } $name = "John Doe"; $apartment = "101"; $timeIn = date("Y-m-d H:i:s"); registerEntry($name, $apartment, $timeIn); sleep(3600); // 1 hour $timeOut = date("Y-m-d H:i:s"); registerExit($name, $apartment, $timeOut); $dbConnection->close();
  4. Na Bling, tenho um produto chamado Esquadro 12" Ramada. Na hora de importar, a Bling monta um arquivo .csv. O Windows abre o arquivo .csv com o programa Excel. e lá você vê o mesmo produto do mesmo jeito que aparece lá na Bling. O problema é na hora de pedir para o PHP ver o arquivo, ele enxerga de maneira totalmente diferente, assim: "Esquadro 12"" Ramada". Eu criei a função aspas, e pedi para o PHP tirar o primeiro e o último aspas do produto. Mas tirar as aspas excedente no meio da descrição é problema. Durante uma semana quebrei a cabeça para resolver o problema. Hoje, eu pedi para o VS Code abrir o arquivo csv, e descobri que o problema não é o PHP, mas sim o arquivo csv. O Excel enxerga o csv de um jeito, mas o VS Code e o PHP enxergam de maneira bem diferente. Graças ao VS Code, consegui montar a função aspas no PHP: arquivo Modelos / Config.php <?php // ... function aspas($bling) { $primeiroCaractere=$bling[0]; $ultimoCaractere=$bling[-1]; if($primeiroCaractere==='"' && $ultimoCaractere==='"') { $bling=substr($bling,1,-1); return str_replace('""','"',$bling); } }
  5. Eu assisti vídeos do professor Guanabara, e com ele eu consegui instalar o WampServe no meu notebook. Essa foi a parte mais difícil do processo, eu levei quatro meses até conseguir o ícone verde na bandeja do Windows. Depois que o ícone do servidor ficar verde, você vai poder escrever no navegador "localhost", vai aparecer a mensagem dos aplicativos à sua disposição (eu já perdi o meu, agora só aparece o diretório do C:\wampserve\www). Depois de cinco meses, eu comecei a aprender a usar o Visual Studio Code, é uma tela preta. Depois de 10 meses, eu consegui montar o meu primeiro arquivo, assim: index.php echo "olá mundo"; mas precisei criar um diretório em c:\wampserve\www\astudy\ Depois de 15 meses é que eu consegui a minha primeira conexão com o MySQL: arquivo index.php <?php $mysqli=new mysqli("localhost","root","","diario"); $query=$mysqli->query("select * from produtos"); while($row=$query->fetch_assoc( )) { echo $row['produto']."<br>"; } Eu não sabia o que era esse "<br>". Em 2024, eu aprendi que "<br>" é um marcador utilizado no HTML. Enfim, já se passaram cinco anos, e eu não sei como programar. Quem me ajuda é a Gemini. Hoje eu perguntei para ela como colocar uma borda na parte de cima de um marcador <tr>, e ela disse que isso é besteira. Só dá para fazer borda no lado de cima com o marcador <td>. <tr> é o marcador de uma linha da tabela, <td> é o marcador de uma célula da tabela. Enfim, para saber um pouco mais de HTML, JavaScript, PHP, MySQL, o melhor é conversar com a Gemini, mas ultimamente ela só responde em inglês. O chato de tudo isso é o inglês. Eu estou apanhando para saber o que é select, var_dump, <input>, <table>, csv, echo, print_r, <a href>, e acho que o professor Guanabara errou ao afirmar que é preciso estudar o HTML e o MySQL antes do PHP. Precisa estudar sim é o inglês antes de tudo. Estou quase desistindo. Mas, além da Gemini, tem o pessoal aqui do fórum (um se chama Iowys e o outro Albano, um responde em maio e dezembro, outro em novembro e agosto). Basta você publicar o código e a imagem que aparece no notebook, assim:
  6. O projeto original trabalhava com quatro campos, manhãHoraEntrada, manhãHoraSaída, TardeHoraEntrada, TardeHoraSaída, eu simplifiquei em apenas dois campos, e assim consegui registrar várias entradas no mesmo dia e até saída no dia seguinte (o relatório ficou péssimo, mas dá para entender mais ou menos o movimento do colaborador ao longo do dia). O projeto original tinha rotina de login, CSS, e o meu projeto não tem nada disso. Aqui o meu foco é o banco de dados e como o PHP é bastante útil dentro do HTML. arquivo /Polo/Controles/ControlePortaria.php <?php $projeto="/Polo"; require_once $_SERVER['DOCUMENT_ROOT']."$projeto/Modelos/Config.php"; class ControlePortaria { private $Conexao; public function __construct() { $this->Conexao=new Conexao; } public function cadastroNovo() { if(isset($_POST['nome'])) { $nome=$_POST['nome']; $verificar=$this->Conexao->select("nome from cadastros where nome='$nome'")[0]->nome; if($verificar) { $mensagem="Já existe $verificar no cadastro"; return view('Mensagem',['mensagem'=>$mensagem]); } $id=$_POST['id']; $imagem=file_get_contents($_FILES['foto']['tmp_name']); $extensao = pathinfo($_FILES['foto']['name'], PATHINFO_EXTENSION); $arquivo="Fotos/$id.$extensao"; file_put_contents($arquivo,$imagem); $this->Conexao->insert("cadastros (nome,foto) values ('$nome','$arquivo')"); return header("location:index.php"); } $id=$this->Conexao->select("max(id) as maximo from cadastros")[0]->maximo+1; return view('CadastroNovo',['id'=>$id]); } public function entrada($id) { $agora=date('Y-m-d H:i'); $this->Conexao->update("movimentos set horaentrada='$agora' where id=$id"); return header("location:index.php"); } public function inicio() { $hoje=date('d/m/y'); $verifica=$this->Conexao->select("* from cadastros"); foreach($verifica as $ver) { $teste=$this->Conexao->select("* from movimentos where idCadastro=$ver->id and horasaida is null"); if(!$teste) { $this->Conexao->insert("movimentos (idCadastro) values ($ver->id)"); } } $cadastros=$this->Conexao->select("cadastros.id, nome, foto, movimentos.id as iid, idCadastro, horaentrada, horasaida from cadastros join movimentos on cadastros.id = movimentos.idCadastro where horasaida is null order by cadastros.nome"); $mensagem=""; if(count($cadastros)==0) { $mensagem="Ninguém foi cadastrado, ainda!"; } return view('Movimento',['cadastros'=>$cadastros,'mensagem'=>$mensagem,'hoje'=>$hoje]); } public function relatorio($dia = null) { $dia=($dia) ? $dia : date('Y-m-d'); $movimentos=$this->Conexao->select("* from movimentos join cadastros on movimentos.idCadastro = cadastros.id where date(horaentrada)='$dia' order by cadastros.nome"); $mensagem=""; if(count($movimentos)==0) { $mensagem="Não houve movimento nesse dia."; } return view('Relatorio',['dia'=>$dia,'movimentos'=>$movimentos,'mensagem'=>$mensagem]); } public function saida($id) { $agora=date('Y-m-d H:i'); $this->Conexao->update("movimentos set horasaida='$agora' where id=$id"); $this->inicio(); } } arquivo /Polo/Fotos/1.png arquivo /Polo/Fotos/2.jpeg arquivo /Polo/Fotos/padrão.jpg arquivo /Polo/Modelos/Conexao.php <?php class Conexao { private static $pdo; public static function instancia() { if (!self::$pdo) { // Veririca se o banco de dados existe $dbName = DBNAME; $checkDbExistsQuery = "SELECT * FROM sys.schema_table_statistics WHERE table_schema = '$dbName'"; try { $tempPdo = new PDO("mysql:host=" . HOST, USER, PASSWORD); $result = $tempPdo->query($checkDbExistsQuery); $dbExists = $result->fetchColumn() === $dbName; $tempPdo = null; // fecha a conexão temporária do PDO } catch (PDOException $e) { die("Erro ao procurar o banco de dados: " . $e->getMessage()); } // Criar o banco de dados se ele não existe if (!$dbExists) { $createDbQuery = "CREATE DATABASE $dbName"; try { $pdo = new PDO("mysql:host=" . HOST, USER, PASSWORD); $pdo->exec($createDbQuery); $pdo->exec("USE ". DBNAME); $pdo->exec("CREATE TABLE `cadastros` (`id` int NOT NULL AUTO_INCREMENT, `nome` varchar(45) NOT NULL,`foto` varchar(45) NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci"); $pdo->exec("CREATE TABLE `movimentos` (`id` int NOT NULL AUTO_INCREMENT, `idCadastro` int NOT NULL,`horaentrada` varchar(20) DEFAULT NULL, `horasaida` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci"); } catch (PDOException $e) { die("Erro ao criar o banco de dados: " . $e->getMessage()); } } // fazer a conexão com o banco de dados self::$pdo = new PDO("mysql:host=" . HOST . ";dbname=" . DBNAME, USER, PASSWORD); } return self::$pdo; } public function delete($sql) { return $this->instancia()->query("delete from $sql"); } public function exec($sql) { return $this->instancia()->query($sql); } public function insert($sql) { return $this->instancia()->query("insert into $sql"); } public function select($sql) { $stmt=$this->instancia()->query("select $sql"); return $stmt->fetchAll(PDO::FETCH_OBJ); } public function update($sql) { return $this->instancia()->query("update $sql"); } } arquivo /Polo/Modelos/Config.php <?php date_default_timezone_set('America/Sao_Paulo'); $baseDir = $_SERVER['DOCUMENT_ROOT'].'/Polo/'; define('PROJETO', $baseDir); define('CONTROLES', PROJETO.'/Controles/'); define('FOTOS',PROJETO.'/Fotos/'); define('MODELOS', PROJETO.'/Modelos/'); define('VISOES', PROJETO.'/Visoes/'); define('HOST', 'localhost'); define('DBNAME','polo'); define('USER','root'); define('PASSWORD',''); spl_autoload_register(function ($classe) { $diretorios = ['Controles', 'Modelos', 'Visoes']; foreach ($diretorios as $diretorio) { $arquivo = PROJETO . DIRECTORY_SEPARATOR . $diretorio . DIRECTORY_SEPARATOR . $classe . '.php'; if (file_exists($arquivo)) { require_once $arquivo; return; } } throw new Exception("Erro ao carregar a classe '{$classe}'. Arquivo não encontrado."); }); function view($arquivo, $array = null) { if (!is_null($array)) { foreach ($array as $var => $value) { ${$var} = $value; } } include VISOES . $arquivo . ".php"; } arquivo /Polo/Visoes/CadastroNovo.php <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Formulário de Cadastro</title> <script> function atualizarImagem() { file = document.getElementById('foto').files[0] reader = new FileReader() reader.onload = function(event) { imageURL = event.target.result; document.getElementById('imagemPreview').src = imageURL; } reader.readAsDataURL(file); } </script> </head> <body style="width:500px;margin:0 auto"> <fieldset> <legend><h3>Formulário de Cadastros id=<?=$id?></h3></legend> <div style=float:left;width:190px> <img src="Fotos/padrão.jpg" height="190" width="150" id=imagemPreview> </div> <div style=float:left;width:250px> <form action="?ControlePortaria.cadastroNovo" method="post" enctype='multipart/form-data'> <table> <tr><td><label for=foto style=display:block>Selecione uma foto</label> <tr><td><input type="file" name="foto" id="foto" onchange="atualizarImagem()"> <tr style=height:20px> <tr><td>Nome: <tr><td><input name="nome" placeholder="Informe o Nome" size=30 required> <input type=hidden name=id value=<?=$id?>> <tr><td><input type=submit value=Gravar> <tr><td><a href='?ControlePortaria.inicio'>Cancelar</a> </table> </form> </div> </fieldset> arquivo /Polo/Visoes/Mensagem.php <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Mensagem</title> </head> <body style="width:500px;margin:0 auto"> <fieldset> <legend><h3>Mensagem</h3></legend> <h4><?=$mensagem?></h4> <h4><a href=index.php>Voltar</a></h4> </fieldset> arquivo /Polo/Visoes/Movimento.php <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Movimento na Portaria</title> <script> function altera(imagem) { if (imagem.height === 10) { imagem.height = 190; } else { imagem.height = 10; } } </script> </head> <body style="width:500px;margin:0 auto"> <fieldset> <legend><h3>Movimento na Portaria em <?=$hoje?> </h3></legend> <form> <input name=nome placeholder="Busca por nome" onchange=submit()> <a href='?ControlePortaria.cadastroNovo'>Cadastrar Pessoas</a> <a href='?ControlePortaria.relatorio'> Relatório</a> </form> <h4><?=$mensagem?></h4> <table> <tr><th>id<th>Pessoa<th>Entrada<th>Saída<th>Foto <?php foreach($cadastros as $c): ?> <tr><td><?=$c->id?><td><?=$c->nome?> <?php if(is_null($c->horaentrada)): $entrada="<input type=submit value='Confirmar' onclick=location.replace('?ControlePortaria.entrada.$c->iid')>"; $saida=null; else: $entrada=date('H:i',strtotime($c->horaentrada)); $saida="<input type=submit value='Confirmar' onclick=location.replace('?ControlePortaria.saida.$c->iid')>"; endif; ?> <td style=text-align:center><?=$entrada?><td><?=$saida?> <td><img src=<?=$c->foto?> height="10" width="150" id=imagem onclick=altera(imagem)> <?php endforeach; ?> </fieldset> arquivo /Polo/Visoes/Relatorio.php <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Relatorio</title> </head> <body style="width:500px;margin:0 auto"> <fieldset> <legend> <h3> Relatorio de <input type=date value=<?=$dia?> onchange='location.replace("?ControlePortaria.relatorio."+this.value)'> <a href=index.php> Voltar</a> </h3> </legend> <h3><?=$mensagem?></h3> <table><th>Nome, Entrada => Saída <?php foreach($movimentos as $m): if(!isset($controle)): $controle=$m->nome; $controle2=0; ?> <tr><td><?=$m->nome?> <?php endif; if($controle!==$m->nome): $controle=$m->nome; $controle2=0; ?> <tr><td><?=$m->nome?> <?php endif; $he=date('H:i',strtotime($m->horaentrada)); $hs=($m->horasaida) ? date('H:i',strtotime($m->horasaida)) : null; $de=date('Y-m-d',strtotime($m->horaentrada)); $ds=($m->horasaida) ?date('Y-m-d',strtotime($m->horasaida)) : null; if($de!==$ds): $hs=($m->horasaida) ?date('d/m H:i',strtotime($m->horasaida)) : null; endif; $controle2++; if($controle2>2): $controle2=0; ?> <tr><td> <?php endif; ?> , <?=$he." => ".$hs?> <?php endforeach; ?> </fieldset> arquivo /Polo/index.php <?php ini_set('display_errors', 1); require __DIR__ . '/Modelos/Config.php'; $rota='ControlePortaria_inicio'; if($_GET) { if(strpos(key($_GET),"_")==0) { exit; } $rota=isset($_GET) ? key($_GET) : $rota; } $segmentos=explode('_',$rota); $nomeControle=$segmentos[0] ?? 'ControlePortaria'; $metodo=$segmentos[1] ?? 'inicio'; $parametro=$segmentos[2] ?? null; $controle=new $nomeControle(); $controle->$metodo($parametro);
  7. Eu estou estudando o projeto polo. O código original está no google drive e tem um tamanho espetacular de 54 mb. Joguei todas as pastas fora e sobrou apenas alguns arquivos php, e o tamanho da pasta polo ficou reduzido em 706 kb. O problema é que eu vi um código HTML assim: <img src="/polo/fotos/padrão.jpg" height="190" width="150" id="foto-cliente"> E eu vi no navegador a imagem da sombra de um homem, quando não esperava ver coisa alguma. Eu limpei a lixeira, reiniciei o Windows duas vezes, mas a imagem continuou aparecendo no navegador. Eu fiquei intrigado, não sabia como o marcador <img> conseguiu "lembrar" da imagem do padrão.jpg. Depois de muito pensar, lembrei que o navegador também tem um repositório de imagens. Pedi para o navegador limpar o histórico da navegação, e assim consegui ver no navegador o que eu esperava, ou seja, nada. Assim, cheguei à conclusão de que o navegador procura imagens primeiro no repositório do navegador e só depois é que ele vai buscar no armazenamento local.
  8. A parte mais difícil da gramática do MySQL, HTML e o PHP é quando eu precisei usar o apóstrofo simples ou duplo (tipo cano 3/4") no histórico ou descrição de um formulário. Para evitar esse problema, eu sempre evitei de usar os apóstrofos. Ontem, no entanto, a Gemini sugeriu usar o comando addslashes do PHP. Agora sim eu posso escrever o que eu quiser no MySQL: <?php // ... $this->Conexao->insert("tbdiario (dia,lcto,contad,contac,valor,hist) values ('$dia',$lcto,$contad,$contac,$valor,'".addslashes($hist)."')");
  9. Aqui eu tento comparar os arquivos csv obtidos na Bling e comparar com o que tem no MySQL: arquivo Modelos / Config.php <?php // ... function aspas($bling) { return str_replace('"','',$bling); } function dec($value) { if($value==null) { return null; } return number_format($value,2,',','.'); } function deca($num) { $value=str_replace(".","",$num); return str_replace(",",".",$value); } arquivo Controles / ControleBling.php <?php class ControleBling extends Controle { private $Conexao; public function __construct() { $this->Conexao=new Conexao; } public function diferenca() { $this->Conexao->exec("truncate table tbprodbling"); $arquivos=['produtos1.csv','produtos2.csv','produtos3.csv','produtos4.csv','produtos5.csv']; foreach($arquivos as $arquivo) { $dados=file($arquivo); foreach($dados as $linha) { $campos=explode(';',$linha); if(aspas($campos[1])!=="Código") { $codprod=intval(trim(aspas($campos[1]))); $un=aspas($campos[3]); $prod=aspas($campos[2]); $custo=deca(aspas($campos[11])); $codbar=trim(aspas($campos[19])); $cf=deca(aspas($campos[4])); $venda=deca(aspas($campos[6])); $this->Conexao->insert("tbprodbling (codprod,un,prod,custo,codbar,cf,venda) values ($codprod,'$un','$prod',$custo,'$codbar','$cf',$venda)"); } } } $produto=$this->Conexao->select("* from tbprod where loc <> 'a24'"); $prodBling=$this->Conexao->select("* from tbprodbling"); echo "O número de registros no MySQL é ".count($produto).".<br>"; echo "O número de registros na Bling é ".count($prodBling).".<br>"; echo "<table><th><th class=text-left>MySQL<th class=text-left>Bling"; foreach($produto as $pr) { $codprod=$pr->codprod; $bling = array_filter($prodBling, function ($produto) use ($codprod) { return $produto->codprod == $codprod;}); $a=current($bling); if(is_null($a)) { echo "<tr><td>Codigo<td><td>Incluir"; } else { $un=($pr->un==$a->un) ? 1 : 0; $prod=($pr->prod==$a->prod) ? 1 : 0; $custo=($pr->custo==$a->custo) ? 1 : 0; $codbar=($pr->codbar==$a->codbar) ? 1 : 0; $cf=($pr->cf==$a->cf) ? 1 : 0; $venda=($pr->venda==$a->venda) ? 1 : 0; if($un.$prod.$custo.$codbar.$cf.$venda !== '111111') { echo "<tr><td>**<td>**<td>**"; echo "<tr><td>Código<td>$pr->codprod<td>$a->codprod"; if($pr->prod!==$a->prod) { echo "<tr><td>Descriçao<td>$pr->prod<td>$a->prod"; } if($pr->custo!==$a->custo) { echo "<tr><td>Custo<td>$pr->custo<td>$a->custo"; } if($pr->codbar!=$a->codbar) { echo "<tr><td>Código de Barra<td>$pr->codbar<td>$a->codbar"; } if($pr->cf!==$a->cf) { echo "<tr><td>NCM<td>$pr->cf<td>$a->cf"; } if($pr->venda!==$a->venda) { echo "<tr><td>Venda<td>$pr->venda<td>$a->venda"; } } } } } }
  10. Esse é um problema difícil de resolver, eu decidi fazer gambiarra: <?php // tb_cadastro (id pk nn ai,nome varchar(45)) InnoDB // (1,"Frank")(2,"João")(3,"Pedro")(4,"Rafael")(5,"Lazaro") session_start(); $conn=mysqli_connect("localhost","root","","polo"); $avancar=(isset($_GET['avancar'])) ? $_GET['avancar'] : null; $where=""; if($avancar) { $id=$_SESSION['referencia']+$avancar; $where="where id >= $id"; } $intervalo=3; $query=$conn->query("select * from tb_cadastro $where order by nome limit $intervalo"); $clientes=$query->fetch_all(MYSQLI_ASSOC); $query=$conn->query("select count(*) as limite from tb_cadastro"); $limite=$query->fetch_assoc()['limite']-$intervalo; $_SESSION['referencia']=($limite>$clientes[0]['id']) ? $clientes[0]['id'] : $limite; $pagina=$intervalo-1; ?> <table> <tr> <td><a href="?avancar=<?=-$pagina?>">Anterior</a> <td><a href="?inicio">Inicio</a> <td><a href="?avancar=<?=$pagina?>" >Posterior</a> <tr> <th>id<th>cliente <?php foreach($clientes as $cliente) : ?> <tr><td><?=$cliente['id']?><td><?=$cliente['nome']?> <?php endforeach; ?> Esse código saiu em desacordo com a estrutura da tabela que você apresentou, mas precisei simplificar para a listagem não ficar longa.
  11. <script> window.open("https://www.example.com", "novaJanela", "width=400,height=300,toolbar=no,location=no,menubar=no,scrollbars=yes,resizable=yes"); </script>
  12. Achei isso com a Gemini: <?php // Verifica se o arquivo foi enviado if (isset($_FILES['arquivo'])) { // Define o nome do arquivo $nomeArquivo = $_FILES['arquivo']['name']; // Define o local de destino $destino = "uploads/" . $nomeArquivo; // Move o arquivo para o destino if (move_uploaded_file($_FILES['arquivo']['tmp_name'], $destino)) { echo "Arquivo salvo com sucesso!"; } else { echo "Erro ao salvar o arquivo."; } } ?>
  13. O código a seguir faz o download do arquivo csv.csv com a ajuda do JavaScript. Ele não deveria funcionar, pois ele está amarrado dentro de um link vazio (href=""). Mas eu consegui fazer funcionar colocando um comando logo abaixo do location.replace. Mas isso só funciona se a página de destino for trabalhar com o download. Se a próxima página não for download, o código Java só vai funcionar se você colocar qualquer coisa no link, na propriedade href. Melhor mesmo é não usar o JavaScript, a sintaxe do link é <a href="paginaDestino.php">Próximo</a>, mas no meu caso precisei apelar para a gambiarra: arquivo csv.csv 1 arquivo index.php <script> function bling() { location.replace("teste.php") alert() } </script> <a href="" onclick=bling()>Bling</a> arquivo teste.php <?php header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("csv.csv")); header('Content-Length: ' . filesize("csv.csv")); ob_get_clean(); readfile("csv.csv");
  14. Finalmente, consegui montar um arquivo csv no servidor e baixar no notebook. O meu problema estava no comando readfile("$pBling.csv"), ele baixava o arquivo csv mas também todo o código HTML que fazia parte do contexto do código PHP. Na base da persistência, encontrei o comando ob_get_clean que "limpa" a área de trabalho e só manda o arquivo csv. arquivo bling.php <?php include('menu.php'); $pedido=$_GET['pedido']; $pBling=$_GET['pBling']; $query=$mysqli->query("select count(bling) as contagem from tbpedido where bling=$pBling"); $verificar=$query->fetch_all(MYSQLI_ASSOC)[0]['contagem']; if($verificar) { exit; } $mysqli->query("update tbpedido set bling=$pBling where ped=$pedido"); $contato="Consumidor Final"; $query=$mysqli->query("select * from tbhistped where ped=$pedido"); $itens=json_decode(json_encode($query->fetch_all(MYSQLI_ASSOC))); $query=$mysqli->query("select sum(subtotal) as soma from tbhistped where subtotal < 0 and ped=$pedido"); $desconto=($query->fetch_assoc()['soma']) ? abs($query->fetch_assoc()['soma']) : 0; $query=$mysqli->query("select total from tbpedido where ped=$pedido"); $total=$query->fetch_assoc()['total']; $query=$mysqli->query("select dia from tbpedido where ped = $pedido"); $data=date('d/m/Y',strtotime($query->fetch_assoc()['dia'])); $dados = array( array("Número pedido","Nome Comprador","Data","CPF/CNPJ Comprador","Endereço Comprador", "Bairro Comprador","Número Comprador","Complemento Comprador","CEP Comprador","Cidade Comprador", "UF Comprador","Telefone Comprador","Celular Comprador","E-mail Comprador","Produto", "SKU","Un","Quantidade","Valor Unitário","Valor Total", "Total Pedido","Valor Frete Pedido","Valor Desconto Pedido","Outras despesas","Nome Entrega", "Endereço Entrega","Número Entrega","Complemento Entrega","Cidade Entrega","UF Entrega", "CEP Entrega","Bairro Entrega","Transportadora","Serviço","Tipo Frete", "Observações","Qtd Parcela","Data Prevista","Vendedor","Forma Pagamento", "ID Forma Pagamento")); foreach($itens as $item) { if($item->subtotal>0) { $dados[]=array($pBling,$contato,$data,null,null, null,null,null,null,null, null,null,null,null,null, $item->codprod,$item->un,$item->qt,$item->unitario,$item->subtotal, $total,null,$desconto,null,null, null,null,null,null,null, null,null,null,null,null, null,1,$data,null,1, 0); } } $arquivo = fopen("$pBling.csv", "w"); fputcsv($arquivo, $dados[0]); foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha); } } fclose($arquivo); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("$pBling.csv")); header('Content-Length: ' . filesize("$pBling.csv")); ob_get_clean(); readfile("$pBling.csv"); unlink("$pBling.csv");
  15. Na hora de mandar o arquivo para a Bling, a Bling se recusou de receber porque estava fora do padrão que ela esperava. Eu fui ver o arquivo, e levei um susto. Hoje eu aprendi que o comando do PHP header( ) é poderoso, mas se tiver alguma ponta solta lá atrás, o resultado é um completo desastre. Para resolver o meu problema, eu tive que tirar o comando include('menu.php'), e no lugar eu criei uma conexão com o banco de dados $mysqli=new mysqli etc. Ou seja, eu devo ter feito muita besteira no arquivo menu.php para atrapalhar o serviço de download do PHP.
  16. Depois de várias tentativas, creio que não é possível fazer mais nada depois que você pede para o PHP fazer o download; se você coloca uma instrução para voltar para o orçamento, ele faz o serviço, mas não faz o download, isso porque o PHP carrega todas as instruções de uma vez para o navegador. Não há como pedir para o PHP fazer por parte, eu até usei o comando sleep. Não sei para que inventaram esse comando. Por outro lado, dá para fazer um monte de gambiarra antes de pedir para o PHP fazer o download com a ajuda do JavaScript, assim: <script> function bling(pedido) { pBling=prompt("digite o número do pedido na Bling") window.location.href="?ControleOrcamento.bling."+pedido+"&pBling="+pBling alert('Por favor, aguarde o download') location.replace() } </script> Essa função foi definida no formulário do orçamento, e ele é executado a partir de um link. O Java Script pede o número do pedido na Bling, a seguir ele pede para o PHP fazer o download, a seguir pede para o usuário aguardar, a seguir o navegador (testei o Chrome e o Edge) confirma o download, e finalmente o usuário clica ok no alerta, e finalmente o Java Script atualiza a tela, onde o usuário vê a confirmação do pedido da Bling no orçamento PHP. Esse Java Script é muito bom, se bem que toda essa improvisação eu consegui na base da tentativa e erro.
  17. Fiquei o dia todo testando o download do PHP, tentando atualizar a tela do orçamento, mas não consegui. Eu só consegui fazer o download funcionar, quando eu pedi para ele não fazer mais nada. Existe algum macete para fazer o download e em seguida pedir para o PHP atualizar a tela do orçamento? A Gemini sugeriu usar o JavaScript para redirecionar, tipo echo "<script>window.location.href='orcamento.php'</script>; o download funcionou, mas o Java Script não. <?php class ControleOrcamento extends Controle { // ... public function bling($pedido) { $pBling=$_GET['pBling']; $this->Conexao->update("tbpedido set bling=$pBling where ped=$pedido"); $contato="Consumidor Final"; $itens=$this->Conexao->select("* from tbhistped where ped=$pedido"); $desconto=$this->Conexao->select("sum(subtotal) as soma from tbhistped where subtotal < 0 and ped=$pedido")[0]->soma; $total=$this->Conexao->select("total from tbpedido where ped=$pedido")[0]->total; $data=date('d/m/Y',strtotime($this->Conexao->select("dia from tbpedido where ped = $pedido")[0]->dia)); $dados = array( array("Número pedido","Nome Comprador","Data","CPF/CNPJ Comprador","Endereço Comprador", "Bairro Comprador","Número Comprador","Complemento Comprador","CEP Comprador","Cidade Comprador", "UF Comprador","Telefone Comprador","Celular Comprador","E-mail Comprador","Produto", "SKU","Un","Quantidade","Valor Unitário","Valor Total", "Total Pedido","Valor Frete Pedido","Valor Desconto Pedido","Outras despesas","Nome Entrega", "Endereço Entrega","Número Entrega","Complemento Entrega","Cidade Entrega","UF Entrega", "CEP Entrega","Bairro Entrega","Transportadora","Serviço","Tipo Frete", "Observações","Qtd Parcela","Data Prevista","Vendedor","Forma Pagamento", "ID Forma Pagamento")); foreach($itens as $item) { if($item->subtotal>0) { $dados[]=array($pBling,$contato,$data,null,null, null,null,null,null,null, null,null,null,null,null, $item->codprod,$item->un,$item->qt,$item->unitario,$item->subtotal, $total,null,$desconto,null,null, null,null,null,null,null, null,null,null,null,null, null,1,$data,null,1, 0); } } $arquivo = fopen("$pBling.csv", "w"); fputcsv($arquivo, $dados[0]); foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha); } } fclose($arquivo); if (file_exists("$pBling.csv")) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("$pBling.csv")); header('Content-Length: ' . filesize("$pBling.csv")); readfile("$pBling.csv"); unlink("$pBling.csv"); } // return header("location:?ControleOrcamento.inicio"); exit; }
  18. tente var_dump($vagas); ou, se preferir: var_dump($vagas[1]); ou você pode personalizar, assim: <?php $vagas=json_decode( '[1,1,[ {"id":"1064992","vaga_id":660,"horaentrada":"2024-04-04 12:03:12", "horalimite":"2024-04-04 12:03:08","pago":null,"incorreto":"0","placa":null, "autuacao_id":null,"autuacao_placa":null,"data_notificacao":null, "regularizado":null,"pagamento_valor":null,"pagamento_tempo":null,"pagamentos": {"valor":0,"tempo":0,"data":null},"minutos":-337}, {"id":"1064993","vaga_id":666,"horaentrada":"2024-04-04 13:27:24", "horalimite":"2024-04-04 13:28:24","pago":0,"incorreto":0,"placa":"AAx1234", "autuacao_id":null,"autuacao_placa":null,"data_notificacao":null, "regularizado":null,"pagamento_valor":null,"pagamento_tempo":null,"pagmentos": {"valor":0,"tempo":0,"data":null},"minutos":-261}]]'); $vagasOcupadas=$vagas[2]; echo "<table><td>Vaga<td>Placa<td>Entrada<td>Limite"; foreach($vagasOcupadas as $vaga) { echo "<tr><td>$vaga->vaga_id<td>$vaga->placa<td>$vaga->horaentrada<td>$vaga->horalimite"; }
  19. Em 2020 não existia a inteligência artificial como a Gemini, desde então fui forçado a usar o marcador <input> para pegar informação do usuário. Aqui em 2024, a Gemini disse que é possível pegar informação do usuário sem o marcador <input>, assim: arquivo index.php <?php class bling { public function __construct() { if(isset($_GET['pedidoPHP'])) { echo "O número do pedido PHP é ".$_GET['pedidoPHP']."<br>"; echo "O número do pedido Bling é ".$_GET['pedidoBling']; exit; } } } (new bling); $pedidoPHP=666; ?> <script> function bling(pedidoPHP) { pedidoBling=prompt("Número do Pedido Bling") window.location.href="?pedidoPHP="+pedidoPHP+"&pedidoBling="+pedidoBling } </script> <a href="#" onclick="bling(<?=$pedidoPHP?>)">Bling</a>
  20. Esse foi difícil, mas eu consegui: <?php $mysqli=new mysqli("localhost","root","","diario"); $vetor=[]; $vetor[]=(object) json_decode('{"1":1}'); $vetor[]=(object) json_decode('{"1":2}'); $vetor[]=(object) json_decode('{"1":3}'); $vetor[]=(object) json_decode('{"2":4}'); print_r($vetor); // Array ( [0] => stdClass Object ( [1] => 1 ) [1] => stdClass Object ( [1] => 2 ) // [2] => stdClass Object ( [1] => 3 ) [3] => stdClass Object ( [2] => 4 ) ) foreach($vetor as $vet) { foreach($vet as $id=>$valor) { $mysqli->query("insert into tabela (id,valor) values ($id,$valor)"); } }
  21. Como não dá para usar a Bling no tablet ou no celular, eu criei essa gambiarra para transformar o notebook numa ponte entre a Hostinger e a Bling. O PHP cria o arquivo CSV no servidor, depois faz o download no notebook, e em seguida o Bling importa o pedido de venda para fazer o resto do serviço. <?php class ControleOrcamento extends Controle { // ... public function bling() { $pedido=63; $contato="Consumidor Final"; $data="30/03/2024"; $dados = array( array("Número pedido","Nome Comprador","Data","CPF/CNPJ Comprador","Endereço Comprador", "Bairro Comprador","Número Comprador","Complemento Comprador","CEP Comprador","Cidade Comprador", "UF Comprador","Telefone Comprador","Celular Comprador","E-mail Comprador","Produto", "SKU","Un","Quantidade","Valor Unitário","Valor Total", "Total Pedido","Valor Frete Pedido","Valor Desconto Pedido","Outras despesas","Nome Entrega", "Endereço Entrega","Número Entrega","Complemento Entrega","Cidade Entrega","UF Entrega", "CEP Entrega","Bairro Entrega","Transportadora","Serviço","Tipo Frete", "Observações","Qtd Parcela","Data Prevista","Vendedor","Forma Pagamento", "ID Forma Pagamento"), array($pedido,$contato,$data,null,null, null,null,null,null,null, null,null,null,null,null, 1604,"pc",1,1,1, 1,null,null,null,null, null,null,null,null,null, null,null,null,null,null, null,1,$data,null,1, 0) ); // Abrir o arquivo CSV para escrita $arquivo = fopen("novo.csv", "w"); // Escrever o cabeçalho do arquivo fputcsv($arquivo, $dados[0]); // Escrever os dados do array no arquivo foreach ($dados as $linha) { if ($linha != $dados[0]) { fputcsv($arquivo, $linha); } } // Fechar o arquivo fclose($arquivo); if (file_exists("novo.csv")) // não usado a variável $arquivo porque o comando exige string e não um componente { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename("novo.csv")); header('Content-Length: ' . filesize("novo.csv")); readfile("novo.csv"); } else { echo "Arquivo não encontrado."; } }
  22. Eu estava estudando um meio de emitir o cupom fiscal em São Paulo e a orientação que recebi da contabilidade é que eu corresse atrás de um programador homologado na Secretaria da Fazenda bem como do aparelho do SAT. O aparelho mais em conta que eu achei foi o da Tanca (R$ 850,00) e o preço da instalação é de R$ 100,00. Eu decidi instalar por conta própria, é bem difícil, o técnico cobra o preço justo, mas eu consegui configurar o aparelho bem como ativar na Sefaz. Consultei dois programadores, e eles me pediram para assinar o plano (um pediu R$ 75,00 por mês, outro pediu R$ 250,00 por mês) que iria instalar e ensinar a como emitir um cupom fiscal. Na internet, eu encontrei a Bling, mas o programa da Bling não emite Cupom Fiscal (CF-e SAT). Para a minha surpresa a Bling me apresentou a NFC-e e eles me informaram que a Nota Fiscal ao Consumidor não precisa da SAT. O portal da NFC-e de São Paulo http://www.nfce.fazenda.sp.gov.br/NFCePortal/Paginas/DuvidasFrequentes.aspx diz que o SAT é obrigatório, já a Bling afirma o contrário. Para resolver esse dilema, eu tirei o SAT do notebook, pedi o credenciamento da NFC-e na Sefaz, peguei o código de segurança do contribuinte, configurei o programa da Bling, mudei o modo teste para o modo produção, e assim consegui conferir que a Bling estava com razão. Estou usando o plano amostra grátis da Bling, ainda tenho 20 dias para testar. O plano mais em conta é o Cromo de R$ 30,00 por mês. Eu gostei da Bling, o único problema é que tudo acontece na internet, onde ninguém pode lhe convencer que os seus dados estão seguros. Para atualizar o banco de dados da Bling estou usando os meus códigos em PHP, o MySQL e o Excel, mas acho que só o Excel é suficiente para o programador ajudar o contribuinte a montar o banco de dados na Bling. Aconselho a usar o Excel CSV, os outros formatos só me deram dor de cabeça. Para corroborar a Bling eu encontrei o artigo 6o. da Portaria CAT 12 de 04/02/2015 que obriga a NFC-e a trabalhar com o SAT bem como a Portaria SRE 34/23 de 05/05/23 que revogou o artigo 6o.
×
×
  • Criar Novo...